public static void SetDock(IArrangedElement element, DockStyle value) { if (GetDock(element) != value) { if (!System.Windows.Forms.ClientUtils.IsEnumValid(value, (int)value, 0, 5)) { throw new InvalidEnumArgumentException("value", (int)value, typeof(DockStyle)); } bool needsDockLayout = CommonProperties.GetNeedsDockLayout(element); CommonProperties.xSetDock(element, value); using (new LayoutTransaction(element.Container as Control, element, PropertyNames.Dock)) { if (value == DockStyle.None) { if (needsDockLayout) { element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.None); UpdateAnchorInfo(element); } } else { element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.All); } } } }
/// <include file='doc\ToolStripControlHost.uex' path='docs/doc[@for="ToolStripControlHost.OnBoundsChanged"]/*' /> /// <devdoc> /// Called when the items bounds are changed. Here, we update the Control's bounds. /// </devdoc> protected override void OnBoundsChanged() { if (control != null) { SuspendSizeSync(); IArrangedElement element = control as IArrangedElement; if (element == null) { Debug.Fail("why are we here? control should not be null"); return; } Size size = LayoutUtils.DeflateRect(this.Bounds, this.Padding).Size; Rectangle bounds = LayoutUtils.Align(size, this.Bounds, ControlAlign); // use BoundsSpecified.None so we dont deal w/specified bounds - this way we can tell what someone has set the size to. element.SetBounds(bounds, BoundsSpecified.None); // sometimes a control can ignore the size passed in, use the adjustment // to re-align. if (bounds != control.Bounds) { bounds = LayoutUtils.Align(control.Size, this.Bounds, ControlAlign); element.SetBounds(bounds, BoundsSpecified.None); } ResumeSizeSync(); } }
public static void SetDock(IArrangedElement element, DockStyle value) { Debug.Assert(!HasCachedBounds(element.Container), "Do not call this method with an active cached bounds list."); if (GetDock(element) != value) { SourceGenerated.EnumValidator.Validate(value); bool dockNeedsLayout = CommonProperties.GetNeedsDockLayout(element); CommonProperties.xSetDock(element, value); using (new LayoutTransaction(element.Container as Control, element, PropertyNames.Dock)) { // if the item is autosized, calling setbounds performs a layout, which // if we havent set the anchor info properly yet makes dock/anchor layout cranky. if (value == DockStyle.None) { if (dockNeedsLayout) { // We are transitioning from docked to not docked, restore the original bounds. element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.None); // Restore Anchor information as its now relevant again. UpdateAnchorInfo(element); } } else { // Now setup the new bounds. element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.All); } } } Debug.Assert(GetDock(element) == value, "Error setting Dock value."); }
private static void xLayoutDockedControl(IArrangedElement element, Rectangle newElementBounds, bool measureOnly, ref Size preferredSize, ref Rectangle remainingBounds) { if (measureOnly) { Size proposedSize = new Size(Math.Max(0, newElementBounds.Width - remainingBounds.Width), Math.Max(0, newElementBounds.Height - remainingBounds.Height)); DockStyle dock = GetDock(element); switch (dock) { case DockStyle.Top: case DockStyle.Bottom: proposedSize.Width = 0; break; } if ((dock == DockStyle.Left) || (dock == DockStyle.Right)) { proposedSize.Height = 0; } if (dock != DockStyle.Fill) { preferredSize += proposedSize; remainingBounds.Size += proposedSize; } else if ((dock == DockStyle.Fill) && CommonProperties.GetAutoSize(element)) { Size size2 = element.GetPreferredSize(proposedSize); remainingBounds.Size += size2; preferredSize += size2; } } else { element.SetBounds(newElementBounds, BoundsSpecified.None); } }
internal static void SetMaximumSize(IArrangedElement element, Size value) { element.Properties.SetSize(_maximumSizeProperty, value); Rectangle bounds = element.Bounds; bounds.Width = Math.Min(bounds.Width, value.Width); bounds.Height = Math.Min(bounds.Height, value.Height); element.SetBounds(bounds, BoundsSpecified.Size); LayoutTransaction.DoLayout(element.Container, element, PropertyNames.MaximumSize); }
protected override void OnBoundsChanged() { if (this.control != null) { this.SuspendSizeSync(); IArrangedElement control = this.control; if (control != null) { Rectangle bounds = LayoutUtils.Align(LayoutUtils.DeflateRect(this.Bounds, this.Padding).Size, this.Bounds, this.ControlAlign); control.SetBounds(bounds, BoundsSpecified.None); if (bounds != this.control.Bounds) { bounds = LayoutUtils.Align(this.control.Size, this.Bounds, this.ControlAlign); control.SetBounds(bounds, BoundsSpecified.None); } this.ResumeSizeSync(); } } }
internal static void SetAutoSize(IArrangedElement element, bool value) { BitVector32 layoutState = GetLayoutState(element); layoutState[_autoSizeSection] = value ? 1 : 0; SetLayoutState(element, layoutState); if (!value) { element.SetBounds(GetSpecifiedBounds(element), BoundsSpecified.None); } }
internal static void SetMinimumSize(IArrangedElement element, Size value) { element.Properties.SetSize(_minimumSizeProperty, value); using (new LayoutTransaction(element.Container as Control, element, PropertyNames.MinimumSize)) { Rectangle bounds = element.Bounds; bounds.Width = Math.Max(bounds.Width, value.Width); bounds.Height = Math.Max(bounds.Height, value.Height); element.SetBounds(bounds, BoundsSpecified.Size); } }
private static void TryCalculatePreferredSizeDockedControl(IArrangedElement element, Rectangle newElementBounds, bool measureOnly, ref Size preferredSize, ref Rectangle remainingBounds) { if (measureOnly) { Size neededSize = new Size( Math.Max(0, newElementBounds.Width - remainingBounds.Width), Math.Max(0, newElementBounds.Height - remainingBounds.Height)); DockStyle dockStyle = GetDock(element); if ((dockStyle == DockStyle.Top) || (dockStyle == DockStyle.Bottom)) { neededSize.Width = 0; } if ((dockStyle == DockStyle.Left) || (dockStyle == DockStyle.Right)) { neededSize.Height = 0; } if (dockStyle != DockStyle.Fill) { preferredSize += neededSize; remainingBounds.Size += neededSize; } else if (dockStyle == DockStyle.Fill && CommonProperties.GetAutoSize(element)) { Size elementPrefSize = element.GetPreferredSize(neededSize); remainingBounds.Size += elementPrefSize; preferredSize += elementPrefSize; } } else { element.SetBounds(newElementBounds, BoundsSpecified.None); #if DEBUG Control control = element as Control; newElementBounds.Size = control.ApplySizeConstraints(newElementBounds.Size); // This usually happens when a Control overrides its SetBoundsCore or sets size during OnResize // to enforce constraints like AutoSize. Generally you can just move this code to Control.GetAdjustedSize // and then PreferredSize will also pick up these constraints. See ComboBox as an example. if (CommonProperties.GetAutoSize(element) && !CommonProperties.GetSelfAutoSizeInDefaultLayout(element)) { Debug.Assert( (newElementBounds.Width < 0 || element.Bounds.Width == newElementBounds.Width) && (newElementBounds.Height < 0 || element.Bounds.Height == newElementBounds.Height), "Element modified its bounds during docking -- PreferredSize will be wrong. See comment near this assert."); } #endif } }
private void ApplyCachedBounds() { for (int i = 0; i < Cells.Count; i++) { IArrangedElement element = Cells[i] as IArrangedElement; if (element.ParticipatesInLayout) { ToolStripPanelCell cell = element as ToolStripPanelCell; element.SetBounds(cell.CachedBounds, BoundsSpecified.None); // Debug.Assert( cell.Control is null || cell.CachedBounds.Location == cell.Control.Bounds.Location, "CachedBounds out of sync with bounds!"); } } }
internal static void SetAutoSize(IArrangedElement element, bool value) { Debug.Assert(value != GetAutoSize(element), "PERF: Caller should guard against setting AutoSize to original value."); BitVector32 state = GetLayoutState(element); state[_autoSizeSection] = value ? 1 : 0; SetLayoutState(element, state); if (value == false) { // If autoSize is being turned off, restore the control to its specified bounds. element.SetBounds(GetSpecifiedBounds(element), BoundsSpecified.None); } Debug.Assert(GetAutoSize(element) == value, "Error detected setting AutoSize."); }
private static void ApplyCachedBounds(IArrangedElement container) { if (CommonProperties.GetAutoSize(container)) { // Avoiding calling DisplayRectangle before checking AutoSize for Everett compat Rectangle displayRectangle = container.DisplayRectangle; if ((displayRectangle.Width == 0) || (displayRectangle.Height == 0)) { ClearCachedBounds(container); return; } } IDictionary dictionary = (IDictionary)container.Properties.GetObject(s_cachedBoundsProperty); if (dictionary != null) { #if DEBUG // In debug builds, we need to modify the collection, so we add a break and an // outer loop to prevent attempting to IEnumerator.MoveNext() on a modified // collection. while (dictionary.Count > 0) { #endif foreach (DictionaryEntry entry in dictionary) { IArrangedElement element = (IArrangedElement)entry.Key; Debug.Assert(element.Container == container, "We have non-children in our containers cached bounds store."); #if DEBUG // We are about to set the bounds to the cached value. We clear the cached value // before SetBounds because some controls fiddle with the bounds on SetBounds // and will callback InitLayout with a different bounds and BoundsSpecified. dictionary.Remove(entry.Key); #endif Rectangle bounds = (Rectangle)entry.Value; element.SetBounds(bounds, BoundsSpecified.None); #if DEBUG break; } #endif } ClearCachedBounds(container); } }
/// SetMinimumSize /// Sets the minimum size for an element. internal static void SetMinimumSize(IArrangedElement element, Size value) { Debug.Assert(value != GetMinimumSize(element, new Size(-7109, -7107)), "PERF: Caller should guard against setting MinimumSize to original value."); element.Properties.SetSize(_minimumSizeProperty, value); using (new LayoutTransaction(element.Container as Control, element, PropertyNames.MinimumSize)) { // Element bounds may need to inflated to new minimum // Rectangle bounds = element.Bounds; bounds.Width = Math.Max(bounds.Width, value.Width); bounds.Height = Math.Max(bounds.Height, value.Height); element.SetBounds(bounds, BoundsSpecified.Size); } Debug.Assert(GetMinimumSize(element, new Size(-7109, -7107)) == value, "Error detected setting MinimumSize."); }
internal static void SetMaximumSize(IArrangedElement element, Size value) { Debug.Assert(value != GetMaximumSize(element, new Size(-7109, -7107)), "PERF: Caller should guard against setting MaximumSize to original value."); element.Properties.SetSize(_maximumSizeProperty, value); // Element bounds may need to truncated to new maximum // Rectangle bounds = element.Bounds; bounds.Width = Math.Min(bounds.Width, value.Width); bounds.Height = Math.Min(bounds.Height, value.Height); element.SetBounds(bounds, BoundsSpecified.Size); // element.SetBounds does a SetBoundsCore. We still need to explicitly refresh parent layout. LayoutTransaction.DoLayout(element.Container, element, PropertyNames.MaximumSize); Debug.Assert(GetMaximumSize(element, new Size(-7109, -7107)) == value, "Error detected setting MaximumSize."); }
private static void ApplyCachedBounds(IArrangedElement container) { if (CommonProperties.GetAutoSize(container)) { Rectangle displayRectangle = container.DisplayRectangle; if ((displayRectangle.Width == 0) || (displayRectangle.Height == 0)) { ClearCachedBounds(container); return; } } IDictionary dictionary = (IDictionary)container.Properties.GetObject(_cachedBoundsProperty); if (dictionary != null) { // Blazor supports keys properly #if BLAZOR foreach (DictionaryEntry entry in dictionary) { IArrangedElement key = (IArrangedElement)entry.Key; Rectangle bounds = (Rectangle)entry.Value; key.SetBounds(bounds, BoundsSpecified.None); } #elif BRIDGE foreach (dynamic entry in dictionary) { IArrangedElement key = (IArrangedElement)entry.key; Rectangle bounds = (Rectangle)entry.value; if (key != null) { key.SetBounds(bounds, BoundsSpecified.None); } } #endif ClearCachedBounds(container); } }
private static void ApplyCachedBounds(IArrangedElement container) { if (CommonProperties.GetAutoSize(container)) { Rectangle displayRectangle = container.DisplayRectangle; if ((displayRectangle.Width == 0) || (displayRectangle.Height == 0)) { ClearCachedBounds(container); return; } } IDict dictionary = (IDict)container.Properties.GetObject(_cachedBoundsProperty); if (dictionary != null) { foreach (dynamic entry in dictionary) { IArrangedElement key = (IArrangedElement)entry.Key; Rectangle bounds = (Rectangle)entry.Value; key.SetBounds(bounds, BoundsSpecified.None); } ClearCachedBounds(container); } }
static void LayoutDockedChildren(IArrangedElement parent, IList controls) { Rectangle space = parent.DisplayRectangle; IArrangedElement mdi = null; // Deal with docking; go through in reverse, MS docs say that lowest Z-order is closest to edge for (int i = controls.Count - 1; i >= 0; i--) { IArrangedElement child = (IArrangedElement)controls[i]; Size child_size = child.Bounds.Size; if (!child.Visible || child.Dock == DockStyle.None) { continue; } // MdiClient never fills the whole area like other controls, have to do it later if (child is MdiClient) { mdi = child; continue; } switch (child.Dock) { case DockStyle.None: // Do nothing break; case DockStyle.Left: if (child.AutoSize) { child_size = child.GetPreferredSize(new Size(0, space.Height)); } child.SetBounds(space.Left, space.Y, child_size.Width, space.Height, BoundsSpecified.None); space.X += child_size.Width; space.Width -= child_size.Width; break; case DockStyle.Top: if (child.AutoSize) { child_size = child.GetPreferredSize(new Size(space.Width, 0)); } child.SetBounds(space.Left, space.Y, space.Width, child_size.Height, BoundsSpecified.None); space.Y += child_size.Height; space.Height -= child_size.Height; break; case DockStyle.Right: if (child.AutoSize) { child_size = child.GetPreferredSize(new Size(0, space.Height)); } child.SetBounds(space.Right - child_size.Width, space.Y, child_size.Width, space.Height, BoundsSpecified.None); space.Width -= child_size.Width; break; case DockStyle.Bottom: if (child.AutoSize) { child_size = child.GetPreferredSize(new Size(space.Width, 0)); } child.SetBounds(space.Left, space.Bottom - child_size.Height, space.Width, child_size.Height, BoundsSpecified.None); space.Height -= child_size.Height; break; case DockStyle.Fill: child.SetBounds(space.Left, space.Top, space.Width, space.Height, BoundsSpecified.None); break; } } // MdiClient gets whatever space is left if (mdi != null) { mdi.SetBounds(space.Left, space.Top, space.Width, space.Height, BoundsSpecified.None); } }
public static void SetDock(IArrangedElement element, DockStyle value) { Debug.Assert(!HasCachedBounds(element.Container), "Do not call this method with an active cached bounds list."); if (GetDock(element) != value) { //valid values are 0x0 to 0x5 if (!ClientUtils.IsEnumValid(value, (int)value, (int)DockStyle.None, (int)DockStyle.Fill)){ throw new InvalidEnumArgumentException("value", (int)value, typeof(DockStyle)); } bool dockNeedsLayout = CommonProperties.GetNeedsDockLayout(element); CommonProperties.xSetDock(element, value); using (new LayoutTransaction(element.Container as Control, element, PropertyNames.Dock)) { // VSWHDIBEY 227715 if the item is autosized, calling setbounds performs a layout, which // if we havent set the anchor info properly yet makes dock/anchor layout cranky. if (value == DockStyle.None) { if (dockNeedsLayout) { // We are transitioning from docked to not docked, restore the original bounds. element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.None); // VSWHIDBEY 159532 restore Anchor information as its now relevant again. UpdateAnchorInfo(element); } } else { // Now setup the new bounds. // element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.All); } } } Debug.Assert(GetDock(element) == value, "Error setting Dock value."); }
// Helper method that either sets the element bounds or does the preferredSize computation based on // the value of measureOnly. private static void xLayoutDockedControl(IArrangedElement element, Rectangle newElementBounds, bool measureOnly, ref Size preferredSize, ref Rectangle remainingBounds) { if (measureOnly) { Size neededSize = new Size( Math.Max(0, newElementBounds.Width - remainingBounds.Width), Math.Max(0, newElementBounds.Height - remainingBounds.Height)); DockStyle dockStyle = GetDock(element); if ((dockStyle == DockStyle.Top) || (dockStyle == DockStyle.Bottom)) { neededSize.Width = 0; } if ((dockStyle == DockStyle.Left) || (dockStyle == DockStyle.Right)) { neededSize.Height = 0; } if (dockStyle != DockStyle.Fill) { preferredSize += neededSize; remainingBounds.Size += neededSize; } else if(dockStyle == DockStyle.Fill && CommonProperties.GetAutoSize(element)) { Size elementPrefSize = element.GetPreferredSize(neededSize); remainingBounds.Size += elementPrefSize; preferredSize += elementPrefSize; } } else { element.SetBounds(newElementBounds, BoundsSpecified.None); #if DEBUG Control control = element as Control; newElementBounds.Size = control.ApplySizeConstraints(newElementBounds.Size); // This usually happens when a Control overrides its SetBoundsCore or sets size during OnResize // to enforce constraints like AutoSize. Generally you can just move this code to Control.GetAdjustedSize // and then PreferredSize will also pick up these constraints. See ComboBox as an example. // if (CommonProperties.GetAutoSize(element) && !CommonProperties.GetSelfAutoSizeInDefaultLayout(element)) { Debug.Assert( (newElementBounds.Width < 0 || element.Bounds.Width == newElementBounds.Width) && (newElementBounds.Height < 0 || element.Bounds.Height == newElementBounds.Height), "Element modified its bounds during docking -- PreferredSize will be wrong. See comment near this assert."); } #endif } }
public static void SetDock(IArrangedElement element, DockStyle value) { if (GetDock(element) != value) { if (!System.Windows.Forms.ClientUtils.IsEnumValid(value, (int) value, 0, 5)) { throw new InvalidEnumArgumentException("value", (int) value, typeof(DockStyle)); } bool needsDockLayout = CommonProperties.GetNeedsDockLayout(element); CommonProperties.xSetDock(element, value); using (new LayoutTransaction(element.Container as Control, element, PropertyNames.Dock)) { if (value == DockStyle.None) { if (needsDockLayout) { element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.None); UpdateAnchorInfo(element); } } else { element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.All); } } } }
/// SetAutoSize /// Sets whether or not the layout engines should treat this control as auto sized. internal static void SetAutoSize(IArrangedElement element, bool value) { Debug.Assert(value != GetAutoSize(element), "PERF: Caller should guard against setting AutoSize to original value."); BitVector32 state = GetLayoutState(element); state[_autoSizeSection] = value ? 1 : 0; SetLayoutState(element, state); if(value == false) { // If autoSize is being turned off, restore the control to its specified bounds. element.SetBounds(GetSpecifiedBounds(element), BoundsSpecified.None); } Debug.Assert(GetAutoSize(element) == value, "Error detected setting AutoSize."); }
/// SetMaximumSize /// Sets the maximum size for an element. internal static void SetMaximumSize(IArrangedElement element, Size value) { Debug.Assert(value != GetMaximumSize(element, new Size(-7109, -7107)), "PERF: Caller should guard against setting MaximumSize to original value."); element.Properties.SetSize(_maximumSizeProperty, value); // Element bounds may need to truncated to new maximum // Rectangle bounds = element.Bounds; bounds.Width = Math.Min(bounds.Width, value.Width); bounds.Height = Math.Min(bounds.Height, value.Height); element.SetBounds(bounds, BoundsSpecified.Size); // element.SetBounds does a SetBoundsCore. We still need to explicitly refresh parent layout. LayoutTransaction.DoLayout(element.Container, element, PropertyNames.MaximumSize); Debug.Assert(GetMaximumSize(element, new Size(-7109, -7107)) == value, "Error detected setting MaximumSize."); }
private void LayoutControls(IArrangedContainer panel, IArrangedElement[,] actual_positions, int[] column_widths, int[] row_heights) { TableLayoutSettings settings = GetLayoutSettings(panel); int border_width = 0; if (panel is TableLayoutPanel table_panel) { border_width = TableLayoutPanel.GetCellBorderWidth(table_panel.CellBorderStyle); } int columns = actual_positions.GetLength(0); int rows = actual_positions.GetLength(1); Point current_pos = new Point(panel.DisplayRectangle.Left + border_width, panel.DisplayRectangle.Top + border_width); for (int y = 0; y < rows; y++) { for (int x = 0; x < columns; x++) { IArrangedElement c = actual_positions[x, y]; if (c != null && c != dummy_control && c.Visible) { Size preferred; int new_x = 0; int new_y = 0; int new_width = 0; int new_height = 0; int column_width = column_widths[x]; for (int i = 1; i < Math.Min(settings.GetColumnSpan(c), column_widths.Length - x); i++) { column_width += column_widths[x + i]; } int column_height = row_heights[y]; for (int i = 1; i < Math.Min(settings.GetRowSpan(c), row_heights.Length - y); i++) { column_height += row_heights[y + i]; } preferred = GetControlSize(c, new Size(column_width - c.Margin.Horizontal, column_height - c.Margin.Vertical)); // Figure out the width of the control if (c.Dock == DockStyle.Fill || c.Dock == DockStyle.Top || c.Dock == DockStyle.Bottom || ((c.Anchor & AnchorStyles.Left) == AnchorStyles.Left && (c.Anchor & AnchorStyles.Right) == AnchorStyles.Right)) { new_width = column_width - c.Margin.Left - c.Margin.Right; } else { new_width = Math.Min(preferred.Width, column_width - c.Margin.Left - c.Margin.Right); } // Figure out the height of the control if (c.Dock == DockStyle.Fill || c.Dock == DockStyle.Left || c.Dock == DockStyle.Right || ((c.Anchor & AnchorStyles.Top) == AnchorStyles.Top && (c.Anchor & AnchorStyles.Bottom) == AnchorStyles.Bottom)) { new_height = column_height - c.Margin.Top - c.Margin.Bottom; } else { new_height = Math.Min(preferred.Height, column_height - c.Margin.Top - c.Margin.Bottom); } // Figure out the left location of the control if (c.Dock == DockStyle.Left || c.Dock == DockStyle.Fill || (c.Anchor & AnchorStyles.Left) == AnchorStyles.Left) { new_x = current_pos.X + c.Margin.Left; } else if (c.Dock == DockStyle.Right || (c.Anchor & AnchorStyles.Right) == AnchorStyles.Right) { new_x = (current_pos.X + column_width) - new_width - c.Margin.Right; } else // (center control) { new_x = (current_pos.X + (column_width - c.Margin.Left - c.Margin.Right) / 2) + c.Margin.Left - (new_width / 2); } // Figure out the top location of the control if (c.Dock == DockStyle.Top || c.Dock == DockStyle.Fill || (c.Anchor & AnchorStyles.Top) == AnchorStyles.Top) { new_y = current_pos.Y + c.Margin.Top; } else if (c.Dock == DockStyle.Bottom || (c.Anchor & AnchorStyles.Bottom) == AnchorStyles.Bottom) { new_y = (current_pos.Y + column_height) - new_height - c.Margin.Bottom; } else // (center control) { new_y = (current_pos.Y + (column_height - c.Margin.Top - c.Margin.Bottom) / 2) + c.Margin.Top - (new_height / 2); } c.SetBounds(new_x, new_y, new_width, new_height, BoundsSpecified.None); } current_pos.Offset(column_widths[x] + border_width, 0); } current_pos.Offset((-1 * current_pos.X) + border_width + panel.DisplayRectangle.Left, row_heights[y] + border_width); } }