Overview

Namespace: TheTechIdea.Beep.Winform.Controls.Design.Server.Docking.Designers
Inheritance: ParentControlDesigner (allows child controls to be dropped onto the panel)
Visibility: internal sealed

DockPanelDesigner provides the design-time experience for individual DockPanel controls. It extends ParentControlDesigner so users can drag child controls onto the panel from the toolbox. It provides 10 designer verbs for docking/manageCommands and intelligent snapping when the panel is moved on the form.

Key Features

  • Auto-key generation — On InitializeNewComponent, a unique Key is derived from the component's site name (e.g., "dockPanel1")
  • Intelligent move snapping — When dragged, panel snaps to nearest dock edge or stacks with overlapped panels
  • Float detection — Dragging outside the host form (>40px boundary) floats the panel
  • 10 designer verbs — Dock Left/Right/Top/Bottom/Fill, Stack with Prev/Next, Move Earlier/Later in Stack, Remove
  • Smart-tag — DockPanelActionList with position, sizing, and behavior properties
  • Resize forwarding — Panel resize delegates to BeepDockingDesignerWiring for proportional recalculation

Designer Verbs (10)

VerbMethodDescription
Dock &LeftApplyDockPosition(Left)Move panel to left edge
Dock &RightApplyDockPosition(Right)Move panel to right edge
Dock &TopApplyDockPosition(Top)Move panel to top edge
Dock &BottomApplyDockPosition(Bottom)Move panel to bottom edge
Dock &FillApplyDockPosition(Fill)Expand to fill remaining space
Stack with Previous PanelStackWithPreviousPanel()Group with previous sibling as tabs
Stack with Next PanelStackWithNextPanel()Group with next sibling as tabs
Move Earlier in StackMoveEarlierInStack()Reorder to earlier tab position
Move Later in StackMoveLaterInStack()Reorder to later tab position
&Remove PanelRemovePanel()Permanently delete the panel

Design-Time Behaviors

Auto-Key on InitializeNewComponent

When a new DockPanel is created (either from the manager's "Add Panel" verb or by drag-dropping), the designer auto-generates a unique Key from the designer host name:

public override void InitializeNewComponent(IDictionary defaultValues)
{
    base.InitializeNewComponent(defaultValues);
    string key = Component.Site?.Name ?? "dockPanel";
    SetPanelProperty("Key", key);
    SetPanelProperty("Title", key);
}

Move Snapping

When the user drags a DockPanel in the designer, the OnDesignerComponentChanged handler detects Bounds/Location/Size changes. For move changes:

  1. FindPanelUnderCenter() — Checks if another panel is at the same parent level under the moved panel's center. If yes, stacks them.
  2. ShouldFloatPanel() — Checks if the panel center is >40px outside the host form bounds. If yes, floats the panel.
  3. ResolveNearestDockPosition() — Calculates the nearest dock edge (Left/Right/Top/Bottom) based on distance from center to host form bounds.

Resize Forwarding

Resize changes are forwarded to BeepDockingDesignerWiring.ResizePanel() for proportional recalculation of adjacent panels.

Selection Tracking

When a DockPanel becomes the primary selection in the designer, BeepDockingDesignerWiring.ActivateDesignPanel() is called to update the docking manager's active panel state.

DockPanelActionList Smart-Tag

PropertyTypeDescription
KeystringUnique panel identifier
TitlestringPanel display title (caption)
DockPositionDockPositionDocked edge
PreferredWidthintPreferred panel width
PreferredHeightintPreferred panel height
MinWidth / MinHeightintMinimum resize dimensions
CanClose / CanFloat / CanAutoHideboolCapability flags
ShowCaptionboolShow/hide panel caption bar

Examples

Snap-to-Edge Logic

private DockPosition ResolveNearestDockPosition()
{
    var panel = (DockPanel)Component;
    var hostBounds = panel.Manager?.HostForm?.Bounds
        ?? panel.Parent?.Bounds;
    var center = new Point(
        panel.Bounds.Left + panel.Bounds.Width / 2,
        panel.Bounds.Top + panel.Bounds.Height / 2);

    // Calculate distances to each edge
    int distLeft = center.X - hostBounds.Left;
    int distRight = hostBounds.Right - center.X;
    int distTop = center.Y - hostBounds.Top;
    int distBottom = hostBounds.Bottom - center.Y;

    // Return nearest edge
    int min = Math.Min(Math.Min(distLeft, distRight),
                       Math.Min(distTop, distBottom));
    if (min == distLeft) return DockPosition.Left;
    if (min == distRight) return DockPosition.Right;
    if (min == distTop) return DockPosition.Top;
    return DockPosition.Bottom;
}