| File: System\Windows\Forms\Layout\ArrangedElement.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms\System.Windows.Forms.csproj (System.Windows.Forms) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Specialized; using System.ComponentModel; using System.Drawing; using System.Windows.Forms.Layout; namespace System.Windows.Forms; internal abstract class ArrangedElement : Component, IArrangedElement { private Rectangle _bounds = Rectangle.Empty; private IArrangedElement? _parent; private BitVector32 _state; private readonly PropertyStore _propertyStore = new(); // Contains all properties that are not always set. private static readonly int s_stateVisible = BitVector32.CreateMask(); internal ArrangedElement() { Padding = DefaultPadding; Margin = DefaultMargin; _state[s_stateVisible] = true; } public Rectangle Bounds { get { return _bounds; } } ArrangedElementCollection IArrangedElement.Children { get { return GetChildren(); } } IArrangedElement? IArrangedElement.Container { get { return GetContainer(); } } protected virtual Padding DefaultMargin { get { return Padding.Empty; } } protected virtual Padding DefaultPadding { get { return Padding.Empty; } } public virtual Rectangle DisplayRectangle { get { Rectangle displayRectangle = Bounds; return displayRectangle; } } public abstract LayoutEngine LayoutEngine { get; } public Padding Margin { get { return CommonProperties.GetMargin(this); } set { Debug.Assert((value.Right >= 0 && value.Left >= 0 && value.Top >= 0 && value.Bottom >= 0), "who's setting margin negative?"); value = LayoutUtils.ClampNegativePaddingToZero(value); if (Margin != value) { CommonProperties.SetMargin(this, value); } } } public virtual Padding Padding { get { return CommonProperties.GetPadding(this, DefaultPadding); } set { Debug.Assert((value.Right >= 0 && value.Left >= 0 && value.Top >= 0 && value.Bottom >= 0), "who's setting padding negative?"); value = LayoutUtils.ClampNegativePaddingToZero(value); if (Padding != value) { CommonProperties.SetPadding(this, value); } } } public virtual IArrangedElement? Parent { get { return _parent; } set { _parent = value; } } public virtual bool ParticipatesInLayout { get { return Visible; } } PropertyStore IArrangedElement.Properties { get { return Properties; } } private PropertyStore Properties { get { return _propertyStore; } } public virtual bool Visible { get { return _state[s_stateVisible]; } set { if (_state[s_stateVisible] != value) { _state[s_stateVisible] = value; if (Parent is not null) { LayoutTransaction.DoLayout(Parent, this, PropertyNames.Visible); } } } } protected abstract IArrangedElement? GetContainer(); protected abstract ArrangedElementCollection GetChildren(); public virtual Size GetPreferredSize(Size constrainingSize) { Size preferredSize = LayoutEngine.GetPreferredSize(this, constrainingSize - Padding.Size) + Padding.Size; return preferredSize; } public virtual void PerformLayout(IArrangedElement container, string? propertyName) { OnLayout(new LayoutEventArgs(container, propertyName)); } protected virtual void OnLayout(LayoutEventArgs e) => LayoutEngine.Layout(this, e); protected virtual void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) { ((IArrangedElement)this).PerformLayout(this, PropertyNames.Size); } public void SetBounds(Rectangle bounds, BoundsSpecified specified) { // in this case the parent is telling us to refresh our bounds - don't // call PerformLayout SetBoundsCore(bounds, specified); } protected virtual void SetBoundsCore(Rectangle bounds, BoundsSpecified specified) { if (bounds != _bounds) { Rectangle oldBounds = _bounds; _bounds = bounds; OnBoundsChanged(oldBounds, bounds); } } }