/// <summary> /// Gets the dock setting for the provided child instance. /// </summary> /// <param name="child">Child view element.</param> /// <returns>Docking setting.</returns> public ViewDockStyle GetDock(ViewBase child) { Debug.Assert(child != null); // Does this element exist in the lookup? if (!_childDocking.ContainsKey(child)) { // No, so add with a default value _childDocking.Add(child, ViewDockStyle.Top); } return(_childDocking[child]); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { Debug.Assert(context != null); // Create new lookup that only contains entries for current child items ViewDockStyleLookup newChildDocking = new ViewDockStyleLookup(); // Remember the original display rectangle provided Rectangle originalRect = context.DisplayRectangle; Rectangle displayRect = context.DisplayRectangle; // 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; 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 Reverse()) { // Add into the valid child lookup ViewDockStyle dockStyle = GetDock(child); newChildDocking.Add(child, dockStyle); // 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(dockStyle)) { 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 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); preferredSize.Width += childSize.Width; preferredSize.Height += childSize.Height; // There can only be one filler! break; } } // Use updated lookup _childDocking = newChildDocking; // 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); // Apply the padding request switch (Orientation) { case VisualOrientation.Top: case VisualOrientation.Bottom: preferredSize.Width += Padding.Horizontal; preferredSize.Height += Padding.Vertical; break; case VisualOrientation.Left: case VisualOrientation.Right: preferredSize.Width += Padding.Vertical; preferredSize.Height += Padding.Horizontal; break; } // Allow the preferred size to be modified before being used return(UpdatePreferredSize(preferredSize)); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { Debug.Assert(context != null); // Create new lookup that only contains entries for current child items ViewDockStyleLookup newChildDocking = new ViewDockStyleLookup(); // Remember the original display rectangle provided Rectangle originalRect = context.DisplayRectangle; Rectangle displayRect = context.DisplayRectangle; // 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; 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()) { // Add into the valid child lookup ViewDockStyle dockStyle = GetDock(child); newChildDocking.Add(child, dockStyle); // 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(dockStyle)) { 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); preferredSize.Width += childSize.Width; preferredSize.Height += childSize.Height; // There can only be one filler! break; } } // Use updated lookup _childDocking = newChildDocking; // 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); // Apply the padding request switch (Orientation) { case VisualOrientation.Top: case VisualOrientation.Bottom: preferredSize.Width += Padding.Horizontal; preferredSize.Height += Padding.Vertical; break; case VisualOrientation.Left: case VisualOrientation.Right: preferredSize.Width += Padding.Vertical; preferredSize.Height += Padding.Horizontal; break; } // Allow the preferred size to be modified before being used return UpdatePreferredSize(preferredSize); }