65.9K
CodeProject is changing. Read more.
Home

Undockable Custom Control in an MDI Application

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.20/5 (5 votes)

Jun 24, 2005

2 min read

viewsIcon

45052

downloadIcon

1315

A custom made control that can be docked and undocked in an MDI application.

Introduction

In this second article of mine I would like to share with you how I made a custom control undockable. Well, before I start I want to mention that I'm not a professional so the code itself is not the best-practice.

Background

The user should be aware of the Windows Forms and controls.

Let's dive into the code!

This is not a tutorial, so I will not define all the steps thoroughly. Just the main points will be covered here; anyway I have provided plenty of comments in the source code for reference.

Well, I made the control undockable in the following way:

  1. Create a Windows application project and make it MDI.
  2. Add a Windows Form (named "Canvas") for adding a child window to the MDI Parent.
  3. Create a user control (named "Toolbar") and add the following code to the buttons:
    private void button1_Click(object sender, System.EventArgs e) 
    //a new child window is created and 
    
    //assigned to the MDIParent...
    
    
    { 
        Canvas canvasForm = new Canvas(); 
    
        //checkes if the control is docked or not...and gets
    
        if (this.ParentForm.IsMdiContainer == true)  
    
        //the MDIContainer correctly according to the situation 
    
    
        { 
            canvasForm.MdiParent = this.ParentForm; 
        } 
        else 
        { 
            canvasForm.MdiParent = this.ParentForm.Owner; 
        } 
        canvasForm.Show();
    } 
    
    
    //docks or undocks the control
    
    private void button2_Click(object sender, System.EventArgs e) 
    { 
        //gets the correct control (docked control 
    
        //or undocked control)
    
        if (this.ParentForm.Text.Length != 0)  
        { 
            this.Visible = false; //docked control is made hidden here... 
    
            if (undockedWnd == null) 
            { 
                //creates the undockedcontrol...and the parent
    
                undockedWnd = new UndockedControl ();  
    
                //form is assigned as its owner 
    
    
                undockedWnd.Owner = this.ParentForm; 
                undockedWnd.Show(); 
            } 
            else 
            //if already created only the "visible" flag is changed to true... 
    
            { 
                undockedWnd.Visible = true; 
            } 
        } 
        else //undocked control 
    
        { 
            //the undocked control is made hidden here...
    
            this.ParentForm.Visible = false;  
            //captures the main parentform...
    
            DrawingGUI prntForm = (DrawingGUI) this.ParentForm.Owner;  
            prntForm.toolBarControl1.Visible = true; 
        }
    }
  4. Add this user control to the main application (MDI application). After adding the control, go and change its accessibility level from private to public. I made this change in order to reach at it later on from the undocked control.
  5. Add a Windows Form (named UndockedControl). Add the "Toolbar" to this form. I also added a ComboBox to the form for the user to change its transparency level.
  6. In the coding of the "Canvas", I have included some code for the Move event of the form in order to rearrange the layout when the scrollbars are displayed. They are not perfect and need much more improvement.

Points of interest

Well for those who are interested in the canvas background that is the gradient color, I'd like to give the following code: (I got it from Using the LinearGradientBrush.)

Add this code in the Paint event of "Canvas" form.

...
Rectangle rect = new Rectangle (pictureBox1.Location, pictureBox1.Size);
LinearGradientBrush br=new LinearGradientBrush(
            rect,
            Color.BlueViolet,
            Color.Black,
            45.0f,
            false);

e.Graphics.FillRectangle(br, rect);

//used for the sample text

StringFormat format = 
   (StringFormat)StringFormat.GenericTypographic.Clone();
Font fn = new Font("Tahoma", 9);
SizeF sf = e.Graphics.MeasureString ("Test String",fn,1024,format);
LinearGradientBrush br3 = 
  new LinearGradientBrush(new RectangleF(pictureBox1.Left,
                      pictureBox1.Top,sf.Width,sf.Height),
                      Color.Yellow,
                      Color.Red,
                      0,
                      false);

e.Graphics.DrawString(
   "Test String", 
   new Font ("Arial", 9, FontStyle.Bold), 
   br3, 
   new Rectangle (rect.X, rect.Y, rect.Width/4, rect.Height), 
   format);
...

I hope this article helps someone out there...if anything goes wrong or there is a better way of coding (I'm sure there is...) please let me know...

History

I have added some code for a flicker-free interface. I have used the .NET way to prevent flickering. I tested it on a WinXP SP2 with .NET 1.1 installed.