Creating a DockablePanel-Controlmanager Using C#, Part 4

Creating a DockablePanel-Controlmanager Using C#, Part 4

In Parts 1-3, you have learned how to create all the parts that are needed to create a DockingManager; you now are able to manage DockableForms on the screen. You have laid out the design and learned how the different parts will work together. You decided to use DockingButtons to offer the user the ability to dock the DockableForms. Apart from that, you have learned that, by using the given design, you are faking a bit, because you really do not dock the forms but instead dock a Panel named DockablePanel You have come to the point where you are able to show these certain buttons on the screen when you start to drag your DockablePanel. If you haven’t read the previous parts of this article series, you need to do so now before you can start with this one, or you will not fully understand the structure and logic of this design pattern. Here are the preceding articles:

Note: Because you have to add some parts here and there, the code becomes more and more complex now and, to be sure where you are, I have added the regions where the code is to find or where it should be created, so that it is easier for you to follow. If you still haven’t created all the regions by now, you really should do this organizational work before; it will save you hours of work.

Hiding the DockingButtons

If you have followed these articles, you probably are burning to get the next point done. After you hold the MouseButton down to drag around a DockablePanel, the DockableButtons appear on the screen, but they do not leave when you stop dragging the Panel around. So, you need to make these buttons invisible when the left MouseButton is up again. Until now, you had the following code in the MouseUp Delegate.

#region Delegates (DockablePanel)
private void HeaderBox_MouseUp(object sender, MouseEventArgs e) {
   if (e.Button == MouseButtons.Left) {
      _isMouseDown = false;

This obviously doesn’t influence the DockingButtons. You need to switch them off where you had switched them on, obviously. This has to be done in the DockingManager. You do this by throwing an event that will have its corresponding delegate in the DockingManager. Therefore, you add a new Delegate definition to the DockingControls namespace in DockablePanel.cs.

internal delegate void CapturedDockControlEventDelegate
   (ControlDockedEventArgs e);

and to the DockablePanel itself, you add an event:

internal event CapturedDockControlEventDelegate

Now, you can fire the event when the left MouseButton is released. The required EventArgs class you already designed in Part 3.

#region Delegates (DockablePanel)
private void HeaderBox_MouseUp(object sender, MouseEventArgs e) {
   if (e.Button == MouseButtons.Left) {
      //_dontDeactivate = true;
      _isMouseDown = false;
      _draggingState = DraggingState.Dropped;
      ControlDockedEventArgs de = new ControlDockedEventArgs();
      // informs about dropping ( mouse Up )
      de.DockControlState = _draggingState;

The method for firing the event is standard to get it fired only when a delegate is connected to it.

#region Methods (DockablePanel)
private void OnDockControlActivities(ControlDockedEventArgs e){
   if (DockControlActivities != null) {

To use the delegate in the DockingManager, you have to add a delegate in the DockingManager class to the DockablePanel. You do that by using the same method you already have used before for the ShowDockControlsEventDelegate. You add it when the DockablePanel is added to the DockingManager and you create the required delegate.

#region Internal Methods (DockingManager)
internal void AddPanel(DockablePanel dockPanel) {
   string key = "P" + _count.ToString();
   // each DockablePanel gets a new number
   // independent from other panels getting closed again.
   // we start with "P0" p for panel
   dockPanel.Key = key;
   AllDockPanels.Add(key, dockPanel);
   dockPanel.DockControlActivities +=
      new CapturedDockControlEventDelegate(dockPanel_Messages);
   dockPanel.ShowDockControls +=
      new ShowDockControlsEventDelegate(dockPanel_ShowDockControls);
   dockPanel.PanelClosing +=
      new DockedFormClosingEventDelegate(dockPanel_PanelClosing);
   // now we attach the carrier to the DockablePanel;
#region Delegates (DockingManager)

private void dockPanel_Messages (ControlDockedEventArgs e){


Now, this delegate will be called every time your left MouseButton is released. Basically, you need that for three different actions that occur when the left MouseButton is released:

  1. DockingButtons and the docking preview (a transparent Window that shows where the docking occurs) need to vanish.
  2. If you are over just one of the DockingButtons when the left MouseButton is released, you are docking your Panel to the corresponding position in the MDI window.
  3. Dragging around is finished without docking if you are not in range of any DockingButton when the left MouseButton is released.

Although the last two points depend on where the mouse actually is positioned during its release, the first point needs to be done in any case.

You also will use the same delegate when the mouse is hovering over a button to show a docking preview depending on which one you are hovering. Therefore, you will need this delegate to differ between these possibilities. For the moment, you do only the following to get the DockingButtons hidden again.

#region Delegates (DockingManager)
private void dockPanel_Messages(ControlDockedEventArgs e) {
   switch (e.DockControlState ) {
      // other conditions are added a bit later
      case DraggingState.Dropped:
         // Hide the DockingButtons

#region Private Methods (DockingManager)
private void HideDockingButtons(){
   // When hideing the Buttons we also have
   // to stop the blinking Cycle of the buttons
   LeftButton.Visible = false;
   RightButton.Visible = false;
   TopButton.Visible = false;
   BottomButton.Visible = false;
   UpperButton.Visible = false;
   LowerButton.Visible = false;
   CenterButton.Visible = false;
   LeftSideButton.Visible = false;
   RightSideButton.Visible = false;

Compile the code now and you will see that the DockingButtons will vanish when the left MouseButton is no longer pressed.

More by Author

Must Read