When the docking position of our composite control is changed we need to ensure
that our child controls are also correctly positioned for the new docking style.
So we override
the inherited Dock
property and recalculate
the correct size and positions as appropriate.
// Override the base class property to allow extra
work
public override DockStyle Dock
{
get { return base.Dock; }
set
{
// Our size
before docking position is changed
Size size
= this.ClientSize;
// Remember
the current docking position
DockStyle
dsOldResize = _resize.Dock;
// New handle
size is dependant on the orientation of the new docking position
_handle.SizeToOrientation(value);
// Modify
docking position of child controls based on our new docking position
_resize.Dock
= DockingControl.ResizeStyleFromControlStyle(value);
_handle.Dock
= DockingControl.HandleStyleFromControlStyle(value);
// Now safe
to update ourself through base class
base.Dock
= value;
// Change
in orientation occured?
if (dsOldResize
!= _resize.Dock)
{
// Must update our client size to ensure the correct size is used when
// the docking position changes. We have to transfer the value that determines
// the vector of the control to the opposite dimension
if ((this.Dock == DockStyle.Top) ||
(this.Dock == DockStyle.Bottom))
size.Height = size.Width;
else
size.Width = size.Height;
this.ClientSize = size;
}
// Repaint
our controls
_handle.Invalidate();
_resize.Invalidate();
}
}
Two static functions (ResizeStyleFromControlStyle
and HandleStyleFromControlStyle
)
are used to find the correct docking style for the _resize
and _handle
controls dependant on the new Dock
style. Of special note is the
code that checks for a change in docking orientation and then changes the Width
or Height
of the control. Remember that when our control is docked
to the top or bottom of the form then the Width
of the control is
calculated for us by the form and the Height
determines how far
inwards the docking control extends. When the orientation moves to be left or
right then we need to update the Width
of the control to reflect
how far from the edge we want the control to extend. So the new Width
should be the old Height
, otherwise the Width
will
remain the same as the entire width of the form and so it would fill the entire
client area.
The rest of the DockingControl
class follows and consists of
static properties for recovering GDI+ objects (to be used by the child controls
for drawing) and the previously mentioned static methods used for calculating
the new docking position of each child control based on the new position of the
DockingControl
.
// Static variables defining colors for drawing
private static Pen _lightPen = new Pen(Color.FromKnownColor(KnownColor.ControlLightLight));
private static Pen _darkPen = new Pen(Color.FromKnownColor(KnownColor.ControlDark));
private static Brush _plainBrush = Brushes.LightGray;
// Static properties for read-only access to drawing colors
public static Pen LightPen
{ get { return _lightPen; } }
public static Pen DarkPen
{ get { return _darkPen; } }
public static Brush PlainBrush { get { return
_plainBrush; } }
public static DockStyle ResizeStyleFromControlStyle(DockStyle
ds)
{
switch(ds)
{
case DockStyle.Left:
return DockStyle.Right;
case DockStyle.Top:
return DockStyle.Bottom;
case DockStyle.Right:
return DockStyle.Left;
case DockStyle.Bottom:
return DockStyle.Top;
default:
// Should
never happen!
throw new
ApplicationException("Invalid DockStyle argument");
}
}
public static DockStyle HandleStyleFromControlStyle(DockStyle
ds)
{
switch(ds)
{
case DockStyle.Left:
return DockStyle.Top;
case DockStyle.Top:
return DockStyle.Left;
case DockStyle.Right:
return DockStyle.Top;
case DockStyle.Bottom:
return DockStyle.Left;
default:
// Should
never happen!
throw new
ApplicationException("Invalid DockStyle argument");
}
}
}
Comments