Thursday, December 11, 2014

How can I make my window or control dock on my mainform just like Visual Studio IDE?

Introduction

How can I make my window or control dock on my mainform just like Visual Studio IDE?
Is there an easier way of making my application more friendly and more customizable?
Here is a component that may help you.

Background

I have been wondering for a long time: there are so many useful controls and components provided in Visual Studio, but why can't I find any docking control for my application?
I also used some third party or free controls for the same purpose, but most of them are not effective enough or they are powerful but do not have enough customization features.
On the other hand, I also want to challenge myself to see if I have the ability to create a tool that meets my own requirements.
Of course, the most important purpose is to provide a useful tool for every programmer who needs it.

Using the Code

The DockLayoutRanger is a WinForm component, and can be added and displayed into the Tool Box List of your Visual Studio IDE.
ToolBox
Then, use it like the other WinForm components, just drag it into your main form, and then theDockLayoutRanger will display as an icon like the image shown below:
Display Icon
If using this component in Visual Studio 2010 or above.
Make sure the [Target Framework] settings of your project can NOT be set to the
[.NET Framework 4 / 3.5 Client Profile] .
Target Framework Settings
Make sure a using statement has been added into your source code:
using System.Windows.Forms;
Now we done with all the prepared job.
Here, we can start creating some Control Panels:
public MainForm()
{
    InitializeComponent();
    
    //Create and setup all controls
    this.projectManagerToolStripMenuItem.Tag = new MyProjectManager("Project Manager");
    this.toolToolStripMenuItem.Tag = new MyToolBox("Tool Box");
    this.propertyWindowToolStripMenuItem.Tag = new MyPropertyView("Property Window");
    this.errorListToolStripMenuItem.Tag = new MyErrorList("Error List");
    this.outputToolStripMenuItem.Tag = new MyOutputBox("Output");
    this.commandToolStripMenuItem.Tag = new MyCommendBox("Command");
}
Start to dock these Control Panels in the location we want:
private void MainForm_Load(object sender, EventArgs e)
{
    //Docking control to the Left side
    this.dockLayoutRanger1.Dock(this, this.toolToolStripMenuItem.Tag as Control, 
    DockStyle.Left);

    //Docking control to the Right side 
    this.dockLayoutRanger1.Dock(this, this.projectManagerToolStripMenuItem.Tag as Control,
    DockStyle.Right);

    //Continue to dock control to the right side of the MainForm
    this.dockLayoutRanger1.Dock(this.propertyWindowToolStripMenuItem.Tag as Control);

    //Docking control to the Bottom
    this.dockLayoutRanger1.Dock(this, this.outputToolStripMenuItem.Tag as Control, 
    DockStyle.Bottom);

    //Continue to dock control to the bottom of the MainForm in Fill Mode
    this.dockLayoutRanger1.Dock(this.commandToolStripMenuItem.Tag as Control, 
    DockStyle.Fill, TabAlignment.Bottom);
}
"Dock" method is the main function that allows us to determine how to arrange our Controls:
 this.dockLayoutRanger1.Dock(
                this, //The container that will be docked
                this.toolToolStripMenuItem.Tag as Control, //The control that will dock 
        //into the container
                DockStyle.Left //How to dock
                );
Quote:
If you set the DockStyle argument to None, then the control will be directly show as a floating window.
Think of this like a sequential flow, if we want to dock a Control into the same side (LeftTopRightBottom) follow the earlier one, the component just needs to know which Control is to be docked instead of Containerand Dockstyle parameters transferring again:
 //Docking control to the Right side 
 this.dockLayoutRanger1.Dock(this, this.projectManagerToolStripMenuItem.Tag as Control, DockStyle.Right);

 //Continue to dock control to the right side of the MainForm
 this.dockLayoutRanger1.Dock(this.propertyWindowToolStripMenuItem.Tag as Control);
Similarly, if we want to dock a Control into the same location with the earlier one, and let the user switch between them by the tabs, we can set the Dockstyle argument to Fill and indicate the TabAlignment we want:
 //Docking control to the Bottom
 this.dockLayoutRanger1.Dock(this, this.outputToolStripMenuItem.Tag as Control, DockStyle.Bottom);

 //Continue to dock control to the bottom of the MainForm in Fill Mode
 this.dockLayoutRanger1.Dock(this.commandToolStripMenuItem.Tag as Control, 
 DockStyle.Fill, TabAlignment.Bottom);
Last, to make sure all of these Control Panels are visible or not when we check any of the corresponding Menuitems, add the statements below into the CheckedChanged event handle function:
  private void menuItem_CheckedChanged(object sender, EventArgs e)
  {
      Control control = (sender as ToolStripMenuItem).Tag as Control;
  
      if (control != null)
      {
          if((sender as ToolStripMenuItem).Checked)
              //Ensure control visible and make it center parent
              this.dockLayoutRanger1.Show(control, true);
              
              //Ensure control visible
              //this.dockLayoutRanger1.Show(control);
          else
              //Force hide control
              this.dockLayoutRanger1.Hide(control);
      }
  }
"Show/Hide" method will force display/hide any Control that has been docked by this component, no matter whether the specified Control has been closed or not and also regardless of whether it is docking into a form or floating like a window now.
Add code lines below to make sure Menu items can be responsive to the corresponding Controls visible status:
  private void viewToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
  {
      foreach (ToolStripItem item in (sender as ToolStripMenuItem).DropDownItems)
      {
          ToolStripMenuItem meniItem = item as ToolStripMenuItem;
  
          if (meniItem != null)
          {
              Control control = meniItem.Tag as Control;
  
              if (control != null)
              {
                  meniItem.CheckedChanged -= new EventHandler(menuItem_CheckedChanged);
  
                  meniItem.Checked = control.Visible && control.TopLevelControl != null;
  
                  meniItem.CheckedChanged += new EventHandler(menuItem_CheckedChanged);
              }
          }
      }
  }
After all of this hard work, now we can get to see a window by running the main program like this:
Default Style
(Of course, the MenuStripToolStripStatusBar and all Control Panels should have been prepared by other work before.)
This is the default style of the component present.
The DockLayoutRanger provides some of the properties that allow you to customize the form style for your own. You could browse all of these properties within the PropertyGrid of Visual Studio IDE:
PropertyGrid01 PropertyGrid 02
( Customizable Properties ) ( Image effect adjusting )
By specify these properties, you could customize many of the visual styles like the text font, backcolor, banner, button images, floating window style, and so on.
So, if you like, you could make your application form look like these:
XP Blue XP OlivXP Silver Win 8
Or these:
Leopard
Silver
Or whatever you want:
Pink
Hope this component will make your development work easier, more efficient and of course, happier.


original article in www.codeproject.com

No comments:

Post a Comment