public override Size GetPreferredSize(ViewLayoutContext context)
{
Debug.Assert(context != null);
// Remember the original display rectangle provided
Rectangle originalRect = context.DisplayRectangle;
Rectangle displayRect = context.DisplayRectangle;
// Border size that is not applied to preferred size
Size borderSize = Size.Empty;
// Accumulate the size that must be provided by docking edges and then filler
Size preferredSize = Size.Empty;
// Track the minimize size needed to satisfy the docking edges only
Size minimumSize = Size.Empty;
if (!IgnoreAllBorderAndPadding)
{
// Apply space the border takes up
if (IgnoreBorderSpace)
borderSize = CommonHelper.ApplyPadding(Orientation, borderSize, context.Renderer.RenderStandardBorder.GetBorderDisplayPadding(_paletteBorder, State, Orientation));
else
{
Padding padding = context.Renderer.RenderStandardBorder.GetBorderDisplayPadding(_paletteBorder, State, Orientation);
preferredSize = CommonHelper.ApplyPadding(Orientation, preferredSize, padding);
displayRect = CommonHelper.ApplyPadding(Orientation, displayRect, padding);
}
// Do we have a metric source for additional padding?
if ((_paletteMetric != null) && (_metricPadding != PaletteMetricPadding.None))
{
// Apply padding needed outside the border of the canvas
Padding padding = _paletteMetric.GetMetricPadding(State, _metricPadding);
preferredSize = CommonHelper.ApplyPadding(Orientation, preferredSize, padding);
displayRect = CommonHelper.ApplyPadding(Orientation, displayRect, padding);
}
}
PaletteDrawBorders leftEdges = PaletteDrawBorders.All;
PaletteDrawBorders rightEdges = PaletteDrawBorders.All;
PaletteDrawBorders topEdges = PaletteDrawBorders.All;
PaletteDrawBorders bottomEdges = PaletteDrawBorders.All;
PaletteDrawBorders fillEdges = PaletteDrawBorders.All;
// Check for edge docking children
foreach (ViewBase child in this.Reverse())
{
// Only position visible children that are not 'fill'
if ((child.Visible || PreferredSizeAll) && (GetDock(child) != ViewDockStyle.Fill))
{
// Prevent children from showing adjacent borders that are not needed
UpdateChildBorders(child, context, ref leftEdges, ref rightEdges,
ref topEdges, ref bottomEdges, ref fillEdges);
// Update with latest calculated display rectangle
context.DisplayRectangle = displayRect;
// Get the preferred size of the child
Size childSize = child.GetPreferredSize(context);
// Apply size requests from edge docking children
switch (OrientateDock(GetDock(child)))
{
case ViewDockStyle.Top:
preferredSize.Height += childSize.Height;
displayRect.Y += childSize.Height;
displayRect.Height -= childSize.Height;
if (minimumSize.Width < childSize.Width)
minimumSize.Width = childSize.Width;
break;
case ViewDockStyle.Bottom:
preferredSize.Height += childSize.Height;
displayRect.Height -= childSize.Height;
if (minimumSize.Width < childSize.Width)
minimumSize.Width = childSize.Width;
break;
case ViewDockStyle.Left:
preferredSize.Width += childSize.Width;
displayRect.X += childSize.Width;
displayRect.Width -= childSize.Width;
if (minimumSize.Height < childSize.Height)
minimumSize.Height = childSize.Height;
break;
case ViewDockStyle.Right:
preferredSize.Width += childSize.Width;
displayRect.Width -= childSize.Width;
if (minimumSize.Height < childSize.Height)
minimumSize.Height = childSize.Height;
break;
}
}
}
// Check for the fill child last
foreach (ViewBase child in this.Reverse())
{
// Only interested in a visible 'fill' child
if ((child.Visible || PreferredSizeAll) && (GetDock(child) == ViewDockStyle.Fill))
{
// Prevent children from showing adjacent borders that are not needed
UpdateChildBorders(child, context, ref leftEdges, ref rightEdges,
ref topEdges, ref bottomEdges, ref fillEdges);
// Update with latest calculated display rectangle
context.DisplayRectangle = displayRect;
// Get the preferred size of the child
Size childSize = child.GetPreferredSize(context);
// Add on the preferred size of the filler
preferredSize.Width += childSize.Width;
preferredSize.Height += childSize.Height;
}
}
// Put back the original display rect
context.DisplayRectangle = originalRect;
// Enforce the minimum values from the other docking edge sizes
preferredSize.Width = Math.Max(preferredSize.Width, minimumSize.Width);
preferredSize.Height = Math.Max(preferredSize.Height, minimumSize.Height);
// Enforce the border sizing as the minimum
preferredSize.Width = Math.Max(preferredSize.Width, borderSize.Width);
preferredSize.Height = Math.Max(preferredSize.Height, borderSize.Height);
return preferredSize;
}