diff --git a/src/Avalonia.Controls/Repeaters/ItemTemplateWrapper.cs b/src/Avalonia.Controls/Repeaters/ItemTemplateWrapper.cs index 86d452742c..00da39cd9d 100644 --- a/src/Avalonia.Controls/Repeaters/ItemTemplateWrapper.cs +++ b/src/Avalonia.Controls/Repeaters/ItemTemplateWrapper.cs @@ -3,9 +3,6 @@ // // Licensed to The Avalonia Project under MIT License, courtesy of The .NET Foundation. -using System; -using System.Collections.Generic; -using System.Text; using Avalonia.Controls.Templates; namespace Avalonia.Controls.Repeaters diff --git a/src/Avalonia.Controls/Repeaters/ItemsRepeater.cs b/src/Avalonia.Controls/Repeaters/ItemsRepeater.cs index f5c832a9e8..2f39d62e08 100644 --- a/src/Avalonia.Controls/Repeaters/ItemsRepeater.cs +++ b/src/Avalonia.Controls/Repeaters/ItemsRepeater.cs @@ -11,18 +11,42 @@ using Avalonia.Input; namespace Avalonia.Controls.Repeaters { + /// + /// Represents a data-driven collection control that incorporates a flexible layout system, + /// custom views, and virtualization. + /// public class ItemsRepeater : Panel { + /// + /// Defines the property. + /// public static readonly AvaloniaProperty HorizontalCacheLengthProperty = AvaloniaProperty.Register(nameof(HorizontalCacheLength), 2.0); + + /// + /// Defines the property. + /// public static readonly StyledProperty ItemTemplateProperty = ItemsControl.ItemTemplateProperty.AddOwner(); + + /// + /// Defines the property. + /// public static readonly DirectProperty ItemsProperty = ItemsControl.ItemsProperty.AddOwner(o => o.Items, (o, v) => o.Items = v); + + /// + /// Defines the property. + /// public static readonly AvaloniaProperty LayoutProperty = AvaloniaProperty.Register(nameof(Layout), new StackLayout()); + + /// + /// Defines the property. + /// public static readonly AvaloniaProperty VerticalCacheLengthProperty = AvaloniaProperty.Register(nameof(VerticalCacheLength), 2.0); + private static readonly AttachedProperty VirtualizationInfoProperty = AvaloniaProperty.RegisterAttached("VirtualizationInfo"); @@ -40,6 +64,9 @@ namespace Avalonia.Controls.Repeaters private ItemsRepeaterElementClearingEventArgs _elementClearingArgs; private ItemsRepeaterElementIndexChangedEventArgs _elementIndexChangedArgs; + /// + /// Initializes a new instance of the class. + /// public ItemsRepeater() { _viewManager = new ViewManager(this); @@ -53,36 +80,61 @@ namespace Avalonia.Controls.Repeaters ClipToBoundsProperty.OverrideDefaultValue(true); } + /// + /// Gets or sets the layout used to size and position elements in the ItemsRepeater. + /// + /// + /// The layout used to size and position elements. The default is a StackLayout with + /// vertical orientation. + /// public Layout Layout { get => GetValue(LayoutProperty); set => SetValue(LayoutProperty, value); } + /// + /// Gets or sets an object source used to generate the content of the ItemsRepeater. + /// public IEnumerable Items { get => _items; set => SetAndRaise(ItemsProperty, ref _items, value); } + /// + /// Gets or sets the template used to display each item. + /// public IDataTemplate ItemTemplate { get => GetValue(ItemTemplateProperty); set => SetValue(ItemTemplateProperty, value); } + /// + /// Gets or sets a value that indicates the size of the buffer used to realize items when + /// panning or scrolling horizontally. + /// public double HorizontalCacheLength { get => GetValue(HorizontalCacheLengthProperty); set => SetValue(HorizontalCacheLengthProperty, value); } + /// + /// Gets or sets a value that indicates the size of the buffer used to realize items when + /// panning or scrolling vertically. + /// public double VerticalCacheLength { get => GetValue(VerticalCacheLengthProperty); set => SetValue(VerticalCacheLengthProperty, value); } + /// + /// Gets a standardized view of the supported interactions between a given Items object and + /// the ItemsRepeater control and its associated components. + /// public ItemsSourceView ItemsSourceView { get; private set; } internal ItemTemplateWrapper ItemTemplateShim { get; set; } @@ -107,19 +159,69 @@ namespace Avalonia.Controls.Repeaters } } + /// + /// Occurs each time an element is cleared and made available to be re-used. + /// + /// + /// This event is raised immediately each time an element is cleared, such as when it falls + /// outside the range of realized items. Elements are cleared when they become available + /// for re-use. + /// public event EventHandler ElementClearing; + + /// + /// Occurs for each realized when the index for the item it + /// represents has changed. + /// + /// + /// When you use ItemsRepeater to build a more complex control that supports specific + /// interactions on the child elements (such as selection or click), it is useful to be + /// able to keep an up-to-date identifier for the backing data item. + /// + /// This event is raised for each realized IControl where the index for the item it + /// represents has changed. For example, when another item is added or removed in the data + /// source, the index for items that come after in the ordering will be impacted. + /// public event EventHandler ElementIndexChanged; + + /// + /// Occurs each time an element is prepared for use. + /// + /// + /// The prepared element might be newly created or an existing element that is being re- + /// used. + /// public event EventHandler ElementPrepared; + /// + /// Retrieves the index of the item from the data source that corresponds to the specified + /// . + /// + /// + /// The element that corresponds to the item to get the index of. + /// + /// + /// The index of the item from the data source that corresponds to the specified UIElement, + /// or -1 if the element is not supported. + /// public int GetElementIndex(IControl element) => GetElementIndexImpl(element); + /// + /// Retrieves the realized UIElement that corresponds to the item at the specified index in + /// the data source. + /// + /// The index of the item. + /// + /// he UIElement that corresponds to the item at the specified index if the item is + /// realized, or null if the item is not realized. + /// public IControl TryGetElement(int index) => GetElementFromIndexImpl(index); - public void PinElement(IControl element) => _viewManager.UpdatePin(element, true); + internal void PinElement(IControl element) => _viewManager.UpdatePin(element, true); - public void UnpinElement(IControl element) => _viewManager.UpdatePin(element, false); + internal void UnpinElement(IControl element) => _viewManager.UpdatePin(element, false); - public IControl GetOrCreateElement(int index) => GetOrCreateElementImpl(index); + internal IControl GetOrCreateElement(int index) => GetOrCreateElementImpl(index); internal static VirtualizationInfo TryGetVirtualizationInfo(IControl element) { diff --git a/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementClearingEventArgs.cs b/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementClearingEventArgs.cs index a6984a3e72..ff011469e7 100644 --- a/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementClearingEventArgs.cs +++ b/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementClearingEventArgs.cs @@ -7,10 +7,18 @@ using System; namespace Avalonia.Controls.Repeaters { + /// + /// Provides data for the event. + /// public class ItemsRepeaterElementClearingEventArgs : EventArgs { internal ItemsRepeaterElementClearingEventArgs(IControl element) => Element = element; + + /// + /// Gets the element that is being cleared for re-use. + /// public IControl Element { get; private set; } + internal void Update(IControl element) => Element = element; } } diff --git a/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementIndexChangedEventArgs.cs b/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementIndexChangedEventArgs.cs index a4457a2b06..c30ba38d23 100644 --- a/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementIndexChangedEventArgs.cs +++ b/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementIndexChangedEventArgs.cs @@ -7,6 +7,9 @@ using System; namespace Avalonia.Controls.Repeaters { + /// + /// Provides data for the event. + /// public class ItemsRepeaterElementIndexChangedEventArgs : EventArgs { internal ItemsRepeaterElementIndexChangedEventArgs(IControl element, int newIndex, int oldIndex) @@ -16,10 +19,19 @@ namespace Avalonia.Controls.Repeaters OldIndex = oldIndex; } + /// + /// Get the element for which the index changed. + /// public IControl Element { get; private set; } + /// + /// Gets the index of the element after the change. + /// public int NewIndex { get; private set; } + /// + /// Gets the index of the element before the change. + /// public int OldIndex { get; private set; } internal void Update(IControl element, int newIndex, int oldIndex) diff --git a/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementPreparedEventArgs.cs b/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementPreparedEventArgs.cs index 12abfa155e..9c26c0d136 100644 --- a/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementPreparedEventArgs.cs +++ b/src/Avalonia.Controls/Repeaters/ItemsRepeaterElementPreparedEventArgs.cs @@ -3,12 +3,11 @@ // // Licensed to The Avalonia Project under MIT License, courtesy of The .NET Foundation. -using System; -using System.Collections.Generic; -using System.Text; - namespace Avalonia.Controls.Repeaters { + /// + /// Provides data for the event. + /// public class ItemsRepeaterElementPreparedEventArgs { internal ItemsRepeaterElementPreparedEventArgs(IControl element, int index) @@ -17,8 +16,14 @@ namespace Avalonia.Controls.Repeaters Index = index; } + /// + /// Gets the prepared element. + /// public IControl Element { get; private set; } + /// + /// Gets the index of the item the element was prepared for. + /// public int Index { get; private set; } internal void Update(IControl element, int index) diff --git a/src/Avalonia.Controls/Repeaters/ItemsSourceView.cs b/src/Avalonia.Controls/Repeaters/ItemsSourceView.cs index f57db0ec07..1caffe881a 100644 --- a/src/Avalonia.Controls/Repeaters/ItemsSourceView.cs +++ b/src/Avalonia.Controls/Repeaters/ItemsSourceView.cs @@ -11,12 +11,26 @@ using System.Linq; namespace Avalonia.Controls.Repeaters { + /// + /// Represents a standardized view of the supported interactions between a given ItemsSource + /// object and an control. + /// + /// + /// Components written to work with ItemsRepeater should consume the + /// via ItemsSourceView since this provides a normalized + /// view of the Items. That way, each component does not need to know if the source is an + /// IEnumerable, an IList, or something else. + /// public class ItemsSourceView : INotifyCollectionChanged, IDisposable { private readonly IList _inner; private INotifyCollectionChanged _notifyCollectionChanged; private int _cachedSize = -1; + /// + /// Initializes a new instance of the ItemsSourceView class for the specified data source. + /// + /// The data source. public ItemsSourceView(IEnumerable source) { Contract.Requires(source != null); @@ -35,6 +49,9 @@ namespace Avalonia.Controls.Repeaters ListenToCollectionChanges(); } + /// + /// Gets the number of items in the collection. + /// public int Count { get @@ -48,11 +65,20 @@ namespace Avalonia.Controls.Repeaters } } + /// + /// Gets a value that indicates whether the items source can provide a unique key for each item. + /// + /// + /// TODO: Not yet implemented in Avalonia. + /// public bool HasKeyIndexMapping => false; - + /// + /// Occurs when the collection has changed to indicate the reason for the change and which items changed. + /// public event NotifyCollectionChangedEventHandler CollectionChanged; + /// public void Dispose() { if (_notifyCollectionChanged != null) @@ -61,13 +87,34 @@ namespace Avalonia.Controls.Repeaters } } + /// + /// Retrieves the item at the specified index. + /// + /// The index. + /// the item. public object GetAt(int index) => _inner[index]; + /// + /// Retrieves the index of the item that has the specified unique identifier (key). + /// + /// The index. + /// The key + /// + /// TODO: Not yet implemented in Avalonia. + /// public string KeyFromIndex(int index) { throw new NotImplementedException(); } + /// + /// Retrieves the unique identifier (key) for the item at the specified index. + /// + /// The key. + /// The index. + /// + /// TODO: Not yet implemented in Avalonia. + /// public int IndexFromKey(string key) { throw new NotImplementedException(); diff --git a/src/Avalonia.Controls/Repeaters/Layout.cs b/src/Avalonia.Controls/Repeaters/Layout.cs index d5f5b215c1..bf7ce95a23 100644 --- a/src/Avalonia.Controls/Repeaters/Layout.cs +++ b/src/Avalonia.Controls/Repeaters/Layout.cs @@ -7,23 +7,100 @@ using System; namespace Avalonia.Controls.Repeaters { + /// + /// Represents the base class for an object that sizes and arranges child elements for a host. + /// public abstract class Layout : AvaloniaObject { - public string LayoutId { get; set; } + internal string LayoutId { get; set; } + /// + /// Occurs when the measurement state (layout) has been invalidated. + /// public event EventHandler MeasureInvalidated; + + /// + /// Occurs when the arrange state (layout) has been invalidated. + /// public event EventHandler ArrangeInvalidated; + /// + /// Initializes any per-container state the layout requires when it is attached to an + /// container. + /// + /// + /// The context object that facilitates communication between the layout and its host + /// container. + /// + /// + /// Container elements that support attached layouts should call this method when a layout + /// instance is first assigned. The container is expected to give the attached layout + /// instance a way to store and retrieve any per-container state by way of the provided + /// context. It is also the responsibility of the container to not reuse the context, or + /// otherwise expose the state from one layout to another. + /// + /// When an attached layout is removed the container should release any reference to the + /// layout state it stored. + /// + /// Override or + /// to provide the behavior for + /// this method in a derived class. + /// public abstract void InitializeForContext(LayoutContext context); + /// + /// Removes any state the layout previously stored on the IControl container. + /// + /// + /// The context object that facilitates communication between the layout and its host + /// container. + /// public abstract void UninitializeForContext(LayoutContext context); + /// + /// Suggests a DesiredSize for a container element. A container element that supports + /// attached layouts should call this method from their own MeasureOverride implementations + /// to form a recursive layout update. The attached layout is expected to call the Measure + /// for each of the container’s IControl children. + /// + /// + /// The context object that facilitates communication between the layout and its host + /// container. + /// + /// + /// The available space that a container can allocate to a child object. A child object can + /// request a larger space than what is available; the provided size might be accommodated + /// if scrolling or other resize behavior is possible in that particular container. + /// + /// public abstract Size Measure(LayoutContext context, Size availableSize); + /// + /// Positions child elements and determines a size for a container UIElement. Container + /// elements that support attached layouts should call this method from their layout + /// override implementations to form a recursive layout update. + /// + /// + /// The context object that facilitates communication between the layout and its host + /// container. + /// + /// + /// The final size that the container computes for the child in layout. + /// + /// The actual size that is used after the element is arranged in layout. public abstract Size Arrange(LayoutContext context, Size finalSize); + /// + /// Invalidates the measurement state (layout) for all IControl containers that reference + /// this layout. + /// protected void InvalidateMeasure() => MeasureInvalidated?.Invoke(this, EventArgs.Empty); + /// + /// Invalidates the arrange state (layout) for all UIElement containers that reference this + /// layout. After the invalidation, the UIElement will have its layout updated, which + /// occurs asynchronously. + /// protected void InvalidateArrange() => ArrangeInvalidated?.Invoke(this, EventArgs.Empty); } } diff --git a/src/Avalonia.Controls/Repeaters/LayoutContext.cs b/src/Avalonia.Controls/Repeaters/LayoutContext.cs index 75ee815fc0..1a4b26c547 100644 --- a/src/Avalonia.Controls/Repeaters/LayoutContext.cs +++ b/src/Avalonia.Controls/Repeaters/LayoutContext.cs @@ -3,16 +3,22 @@ // // Licensed to The Avalonia Project under MIT License, courtesy of The .NET Foundation. -using System; -using System.Collections.Generic; -using System.Text; - namespace Avalonia.Controls.Repeaters { + /// + /// Represents the base class for an object that facilitates communication between an attached + /// layout and its host container. + /// public class LayoutContext : AvaloniaObject { + /// + /// Gets or sets an object that represents the state of a layout. + /// public object LayoutState { get; set; } + /// + /// Implements the behavior of in a derived or custom LayoutContext. + /// protected virtual object LayoutStateCore { get; set; } } } diff --git a/src/Avalonia.Controls/Repeaters/NonVirtualizingLayout.cs b/src/Avalonia.Controls/Repeaters/NonVirtualizingLayout.cs index 95a66834a0..bac2e10f88 100644 --- a/src/Avalonia.Controls/Repeaters/NonVirtualizingLayout.cs +++ b/src/Avalonia.Controls/Repeaters/NonVirtualizingLayout.cs @@ -3,12 +3,12 @@ // // Licensed to The Avalonia Project under MIT License, courtesy of The .NET Foundation. -using System; -using System.Collections.Generic; -using System.Text; - namespace Avalonia.Controls.Repeaters { + /// + /// Represents the base class for an object that sizes and arranges child elements for a host + /// and and does not support virtualization. + /// public abstract class NonVirtualizingLayout : Layout { } diff --git a/src/Avalonia.Controls/Repeaters/StackLayout.cs b/src/Avalonia.Controls/Repeaters/StackLayout.cs index 2377061d60..8b887b149e 100644 --- a/src/Avalonia.Controls/Repeaters/StackLayout.cs +++ b/src/Avalonia.Controls/Repeaters/StackLayout.cs @@ -8,34 +8,57 @@ using System.Collections.Specialized; namespace Avalonia.Controls.Repeaters { + /// + /// Arranges elements into a single line (with spacing) that can be oriented horizontally or vertically. + /// public class StackLayout : VirtualizingLayout, IFlowLayoutAlgorithmDelegates { + /// + /// Defines the property. + /// public static readonly StyledProperty OrientationProperty = StackPanel.OrientationProperty.AddOwner(); + /// + /// Defines the property. + /// public static readonly StyledProperty SpacingProperty = StackPanel.SpacingProperty.AddOwner(); private readonly OrientationBasedMeasures _orientation = new OrientationBasedMeasures(); + /// + /// Initializes a new instance of the StackLayout class. + /// public StackLayout() { LayoutId = "StackLayout"; } + /// + /// Gets or sets the axis along which items are laid out. + /// + /// + /// One of the enumeration values that specifies the axis along which items are laid out. + /// The default is Vertical. + /// public Orientation Orientation { get => GetValue(OrientationProperty); set => SetValue(OrientationProperty, value); } + /// + /// Gets or sets a uniform distance (in pixels) between stacked items. It is applied in the + /// direction of the StackLayout's Orientation. + /// public double Spacing { get => GetValue(SpacingProperty); set => SetValue(SpacingProperty, value); } - public Rect GetExtent( + internal Rect GetExtent( Size availableSize, VirtualizingLayoutContext context, IControl firstRealized, @@ -73,7 +96,7 @@ namespace Avalonia.Controls.Repeaters return extent; } - public void OnElementMeasured( + internal void OnElementMeasured( IControl element, int index, Size availableSize, diff --git a/src/Avalonia.Controls/Repeaters/StackLayoutState.cs b/src/Avalonia.Controls/Repeaters/StackLayoutState.cs index 9ffc5be586..130522c908 100644 --- a/src/Avalonia.Controls/Repeaters/StackLayoutState.cs +++ b/src/Avalonia.Controls/Repeaters/StackLayoutState.cs @@ -9,6 +9,9 @@ using System.Linq; namespace Avalonia.Controls.Repeaters { + /// + /// Represents the state of a StackLayout. + /// public class StackLayoutState { private const int BufferSize = 100; diff --git a/src/Avalonia.Controls/Repeaters/UniformGridLayout.cs b/src/Avalonia.Controls/Repeaters/UniformGridLayout.cs index 633f1a968d..4c2327b15b 100644 --- a/src/Avalonia.Controls/Repeaters/UniformGridLayout.cs +++ b/src/Avalonia.Controls/Repeaters/UniformGridLayout.cs @@ -8,43 +8,111 @@ using System.Collections.Specialized; namespace Avalonia.Controls.Repeaters { + /// + /// Defines constants that specify how items are aligned on the non-scrolling or non-virtualizing axis. + /// public enum UniformGridLayoutItemsJustification { + /// + /// Items are aligned with the start of the row or column, with extra space at the end. + /// Spacing between items does not change. + /// Start = 0, + + /// + /// Items are aligned in the center of the row or column, with extra space at the start and + /// end. Spacing between items does not change. + /// Center = 1, + + /// + /// Items are aligned with the end of the row or column, with extra space at the start. + /// Spacing between items does not change. + /// End = 2, + + /// + /// Items are aligned so that extra space is added evenly before and after each item. + /// SpaceAround = 3, + + /// + /// Items are aligned so that extra space is added evenly between adjacent items. No space + /// is added at the start or end. + /// SpaceBetween = 4, + SpaceEvenly = 5, }; + /// + /// Defines constants that specify how items are sized to fill the available space. + /// public enum UniformGridLayoutItemsStretch { + /// + /// The item retains its natural size. Use of extra space is determined by the + /// property. + /// None = 0, + + /// + /// The item is sized to fill the available space in the non-scrolling direction. Item size + /// in the scrolling direction is not changed. + /// Fill = 1, + + /// + /// The item is sized to both fill the available space in the non-scrolling direction and + /// maintain its aspect ratio. + /// Uniform = 2, }; + /// + /// Positions elements sequentially from left to right or top to bottom in a wrapping layout. + /// public class UniformGridLayout : VirtualizingLayout, IFlowLayoutAlgorithmDelegates { + /// + /// Defines the property. + /// public static readonly StyledProperty ItemsJustificationProperty = AvaloniaProperty.Register(nameof(ItemsJustification)); + /// + /// Defines the property. + /// public static readonly StyledProperty ItemsStretchProperty = AvaloniaProperty.Register(nameof(ItemsStretch)); + /// + /// Defines the property. + /// public static readonly StyledProperty MinColumnSpacingProperty = AvaloniaProperty.Register(nameof(MinColumnSpacing)); + /// + /// Defines the property. + /// public static readonly StyledProperty MinItemHeightProperty = AvaloniaProperty.Register(nameof(MinItemHeight)); + /// + /// Defines the property. + /// public static readonly StyledProperty MinItemWidthProperty = AvaloniaProperty.Register(nameof(MinItemWidth)); + /// + /// Defines the property. + /// public static readonly StyledProperty MinRowSpacingProperty = AvaloniaProperty.Register(nameof(MinRowSpacing)); + /// + /// Defines the property. + /// public static readonly StyledProperty OrientationProperty = StackPanel.OrientationProperty.AddOwner(); @@ -56,6 +124,9 @@ namespace Avalonia.Controls.Repeaters private UniformGridLayoutItemsJustification _itemsJustification; private UniformGridLayoutItemsStretch _itemsStretch; + /// + /// Initializes a new instance of the class. + /// public UniformGridLayout() { LayoutId = "UniformGridLayout"; @@ -66,42 +137,95 @@ namespace Avalonia.Controls.Repeaters OrientationProperty.OverrideDefaultValue(Orientation.Horizontal); } + /// + /// Gets or sets a value that indicates how items are aligned on the non-scrolling or non- + /// virtualizing axis. + /// + /// + /// An enumeration value that indicates how items are aligned. The default is Start. + /// public UniformGridLayoutItemsJustification ItemsJustification { get => GetValue(ItemsJustificationProperty); set => SetValue(ItemsJustificationProperty, value); } + /// + /// Gets or sets a value that indicates how items are sized to fill the available space. + /// + /// + /// An enumeration value that indicates how items are sized to fill the available space. + /// The default is None. + /// + /// + /// This property enables adaptive layout behavior where the items are sized to fill the + /// available space along the non-scrolling axis, and optionally maintain their aspect ratio. + /// public UniformGridLayoutItemsStretch ItemsStretch { get => GetValue(ItemsStretchProperty); set => SetValue(ItemsStretchProperty, value); } + /// + /// Gets or sets the minimum space between items on the horizontal axis. + /// + /// + /// The spacing may exceed this minimum value when is set + /// to SpaceEvenly, SpaceAround, or SpaceBetween. + /// public double MinColumnSpacing { get => GetValue(MinColumnSpacingProperty); set => SetValue(MinColumnSpacingProperty, value); } + /// + /// Gets or sets the minimum height of each item. + /// + /// + /// The minimum height (in pixels) of each item. The default is NaN, in which case the + /// height of the first item is used as the minimum. + /// public double MinItemHeight { get => GetValue(MinItemHeightProperty); set => SetValue(MinItemHeightProperty, value); } + /// + /// Gets or sets the minimum width of each item. + /// + /// + /// The minimum width (in pixels) of each item. The default is NaN, in which case the width + /// of the first item is used as the minimum. + /// public double MinItemWidth { get => GetValue(MinItemWidthProperty); set => SetValue(MinItemWidthProperty, value); } + /// + /// Gets or sets the minimum space between items on the vertical axis. + /// + /// + /// The spacing may exceed this minimum value when is set + /// to SpaceEvenly, SpaceAround, or SpaceBetween. + /// public double MinRowSpacing { get => GetValue(MinRowSpacingProperty); set => SetValue(MinRowSpacingProperty, value); } + /// + /// Gets or sets the axis along which items are laid out. + /// + /// + /// One of the enumeration values that specifies the axis along which items are laid out. + /// The default is Vertical. + /// public Orientation Orientation { get => GetValue(OrientationProperty); diff --git a/src/Avalonia.Controls/Repeaters/UniformGridLayoutState.cs b/src/Avalonia.Controls/Repeaters/UniformGridLayoutState.cs index 0570c1dde2..5095ff35a6 100644 --- a/src/Avalonia.Controls/Repeaters/UniformGridLayoutState.cs +++ b/src/Avalonia.Controls/Repeaters/UniformGridLayoutState.cs @@ -10,6 +10,9 @@ using System.Text; namespace Avalonia.Controls.Repeaters { + /// + /// Represents the state of a . + /// public class UniformGridLayoutState { // We need to measure the element at index 0 to know what size to measure all other items. diff --git a/src/Avalonia.Controls/Repeaters/VirtualizingLayout.cs b/src/Avalonia.Controls/Repeaters/VirtualizingLayout.cs index 02700f716c..08c72b188e 100644 --- a/src/Avalonia.Controls/Repeaters/VirtualizingLayout.cs +++ b/src/Avalonia.Controls/Repeaters/VirtualizingLayout.cs @@ -3,47 +3,109 @@ // // Licensed to The Avalonia Project under MIT License, courtesy of The .NET Foundation. -using System; -using System.Collections.Generic; using System.Collections.Specialized; -using System.Text; namespace Avalonia.Controls.Repeaters { + /// + /// Represents the base class for an object that sizes and arranges child elements for a host + /// and supports virtualization. + /// public abstract class VirtualizingLayout : Layout { + /// public sealed override void InitializeForContext(LayoutContext context) { InitializeForContextCore((VirtualizingLayoutContext)context); } + /// public sealed override void UninitializeForContext(LayoutContext context) { UninitializeForContextCore((VirtualizingLayoutContext)context); } + /// public sealed override Size Measure(LayoutContext context, Size availableSize) { return MeasureOverride((VirtualizingLayoutContext)context, availableSize); } + /// public sealed override Size Arrange(LayoutContext context, Size finalSize) { return ArrangeOverride((VirtualizingLayoutContext)context, finalSize); } + /// + /// When overridden in a derived class, initializes any per-container state the layout + /// requires when it is attached to an IControl container. + /// + /// + /// The context object that facilitates communication between the layout and its host + /// container. + /// protected virtual void InitializeForContextCore(VirtualizingLayoutContext context) { } + /// + /// When overridden in a derived class, removes any state the layout previously stored on + /// the IControl container. + /// + /// + /// The context object that facilitates communication between the layout and its host + /// container. + /// protected virtual void UninitializeForContextCore(VirtualizingLayoutContext context) { } + /// + /// Provides the behavior for the "Measure" pass of the layout cycle. Classes can override + /// this method to define their own "Measure" pass behavior. + /// + /// + /// The context object that facilitates communication between the layout and its host + /// container. + /// + /// + /// The available size that this object can give to child objects. Infinity can be + /// specified as a value to indicate that the object will size to whatever content is + /// available. + /// + /// + /// The size that this object determines it needs during layout, based on its calculations + /// of the allocated sizes for child objects or based on other considerations such as a + /// fixed container size. + /// protected abstract Size MeasureOverride(VirtualizingLayoutContext context, Size availableSize); + /// + /// When implemented in a derived class, provides the behavior for the "Arrange" pass of + /// layout. Classes can override this method to define their own "Arrange" pass behavior. + /// + /// + /// The context object that facilitates communication between the layout and its host + /// container. + /// + /// + /// The final area within the container that this object should use to arrange itself and + /// its children. + /// + /// The actual size that is used after the element is arranged in layout. protected virtual Size ArrangeOverride(VirtualizingLayoutContext context, Size finalSize) => finalSize; + /// + /// Notifies the layout when the data collection assigned to the container element (Items) + /// has changed. + /// + /// + /// The context object that facilitates communication between the layout and its host + /// container. + /// + /// The data source. + /// Data about the collection change. protected internal virtual void OnItemsChangedCore( VirtualizingLayoutContext context, object source,