|
@@ -9,34 +9,44 @@ namespace Avalonia.Controls.Generators
|
|
|
/// When creating a container for an item from a <see cref="VirtualizingPanel"/>, the following
|
|
|
/// process should be followed:
|
|
|
///
|
|
|
- /// - <see cref="IsItemItsOwnContainer(Control)"/> should first be called if the item is
|
|
|
- /// derived from the <see cref="Control"/> class. If this method returns true then the
|
|
|
- /// item itself should be used as the container.
|
|
|
- /// - If <see cref="IsItemItsOwnContainer(Control)"/> returns false then
|
|
|
- /// <see cref="CreateContainer"/> should be called to create a new container.
|
|
|
+ /// - <see cref="NeedsContainer(object, int, out object?)"/> should first be called to
|
|
|
+ /// determine whether the item needs a container. This method will return true if the item
|
|
|
+ /// should be wrapped in a container control, or false if the item itself can be used as a
|
|
|
+ /// container.
|
|
|
+ /// - If <see cref="NeedsContainer(object, int, out object?)"/> returns true then the
|
|
|
+ /// <see cref="CreateContainer"/> method should be called to create a new container, passing
|
|
|
+ /// the recycle key returned from <see cref="NeedsContainer(object, int, out object?)"/>.
|
|
|
+ /// - If the panel supports recycling and the recycle key is non-null then the recycle key
|
|
|
+ /// should be recorded for the container (e.g. in an attached property or the realized
|
|
|
+ /// container list).
|
|
|
/// - <see cref="PrepareItemContainer(Control, object?, int)"/> method should be called for the
|
|
|
/// container.
|
|
|
/// - The container should then be added to the panel using
|
|
|
/// <see cref="VirtualizingPanel.AddInternalChild(Control)"/>
|
|
|
/// - Finally, <see cref="ItemContainerPrepared(Control, object?, int)"/> should be called.
|
|
|
///
|
|
|
- /// NOTE: If <see cref="IsItemItsOwnContainer(Control)"/> in the first step above returns true
|
|
|
- /// then the above steps should be carried out a single time; the first time the item is
|
|
|
- /// displayed. Otherwise the steps should be carried out each time a new container is realized
|
|
|
- /// for an item.
|
|
|
+ /// NOTE: If <see cref="NeedsContainer(object, int, out object?)"/> in the first step above
|
|
|
+ /// returns false then the above steps should be carried out a single time: the first time the
|
|
|
+ /// item is displayed. Otherwise the steps should be carried out each time a new container is
|
|
|
+ /// realized for an item.
|
|
|
///
|
|
|
/// When unrealizing a container, the following process should be followed:
|
|
|
///
|
|
|
- /// - If <see cref="IsItemItsOwnContainer(Control)"/> for the item returned true then the item
|
|
|
- /// cannot be unrealized or recycled.
|
|
|
+ /// - If <see cref="NeedsContainer(object, int, out object?)"/> for the item returned false
|
|
|
+ /// then the item cannot be unrealized or recycled.
|
|
|
/// - Otherwise, <see cref="ClearItemContainer(Control)"/> should be called for the container
|
|
|
- /// - If recycling is supported then the container should be added to a recycle pool.
|
|
|
- /// - It is assumed that recyclable containers will not be removed from the panel but instead
|
|
|
- /// hidden from view using e.g. `container.IsVisible = false`.
|
|
|
+ /// - If recycling is supported by the panel and the container then the container should be
|
|
|
+ /// added to a recycle pool keyed on the recycle key returned from
|
|
|
+ /// <see cref="NeedsContainer(object, int, out object?)"/>. It is assumed that recycled
|
|
|
+ /// containers will not be removed from the panel but instead hidden from view using
|
|
|
+ /// e.g. `container.IsVisible = false`.
|
|
|
+ /// - If recycling is not supported then the container should be removed from the panel.
|
|
|
///
|
|
|
/// When recycling an unrealized container, the following process should be followed:
|
|
|
///
|
|
|
- /// - An element should be taken from the recycle pool.
|
|
|
+ /// - <see cref="NeedsContainer(object, int, out object?)"/> should be called to determine
|
|
|
+ /// whether the item needs a container, and if so, the recycle key.
|
|
|
+ /// - A container should be taken from the recycle pool keyed on the returned recycle key.
|
|
|
/// - The container should be made visible.
|
|
|
/// - <see cref="PrepareItemContainer(Control, object?, int)"/> method should be called for the
|
|
|
/// container.
|
|
@@ -54,28 +64,43 @@ namespace Avalonia.Controls.Generators
|
|
|
internal ItemContainerGenerator(ItemsControl owner) => _owner = owner;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Creates a new container control.
|
|
|
+ /// Determines whether the specified item needs to be wrapped in a container control.
|
|
|
/// </summary>
|
|
|
- /// <returns>The newly created container control.</returns>
|
|
|
- /// <remarks>
|
|
|
- /// Before calling this method, <see cref="IsItemItsOwnContainer(Control)"/> should be
|
|
|
- /// called to determine whether the item itself should be used as a container. After
|
|
|
- /// calling this method, <see cref="PrepareItemContainer(Control, object, int)"/> should
|
|
|
- /// be called to prepare the container to display the specified item.
|
|
|
- /// </remarks>
|
|
|
- public Control CreateContainer() => _owner.CreateContainerForItemOverride();
|
|
|
+ /// <param name="item">The item to display.</param>
|
|
|
+ /// <param name="index">The index of the item.</param>
|
|
|
+ /// <param name="recycleKey">
|
|
|
+ /// When the method returns, contains a key that can be used to locate a previously
|
|
|
+ /// recycled container of the correct type, or null if the item cannot be recycled.
|
|
|
+ /// </param>
|
|
|
+ /// <returns>
|
|
|
+ /// true if the item needs a container; otherwise false if the item can itself be used
|
|
|
+ /// as a container.
|
|
|
+ /// </returns>
|
|
|
+ public bool NeedsContainer(object? item, int index, out object? recycleKey) =>
|
|
|
+ _owner.NeedsContainerOverride(item, index, out recycleKey);
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Determines whether the specified item is (or is eligible to be) its own container.
|
|
|
+ /// Creates a new container control.
|
|
|
/// </summary>
|
|
|
- /// <param name="container">The item.</param>
|
|
|
- /// <returns>true if the item is its own container, otherwise false.</returns>
|
|
|
+ /// <param name="item">The item to display.</param>
|
|
|
+ /// <param name="index">The index of the item.</param>
|
|
|
+ /// <param name="recycleKey">
|
|
|
+ /// The recycle key returned from <see cref="NeedsContainer(object, int, out object?)"/>
|
|
|
+ /// </param>
|
|
|
+ /// <returns>The newly created container control.</returns>
|
|
|
/// <remarks>
|
|
|
- /// Whereas in WPF/UWP, non-control items can be their own container, in Avalonia only
|
|
|
- /// control items may be; the caller is responsible for checking if each item is a control
|
|
|
- /// and calling this method before creating a new container.
|
|
|
+ /// Before calling this method, <see cref="NeedsContainer(object, int, out object?)"/>
|
|
|
+ /// should be called to determine whether the item itself should be used as a container.
|
|
|
+ /// After calling this method, <see cref="PrepareItemContainer(Control, object, int)"/>
|
|
|
+ /// must be called to prepare the container to display the specified item.
|
|
|
+ ///
|
|
|
+ /// If the panel supports recycling then the returned recycle key should be stored alongside
|
|
|
+ /// the container and when container becomes eligible for recycling the container should
|
|
|
+ /// be placed in a recycle pool using this key. If the returned recycle key is null then
|
|
|
+ /// the container cannot be recycled.
|
|
|
/// </remarks>
|
|
|
- public bool IsItemItsOwnContainer(Control container) => _owner.IsItemItsOwnContainerOverride(container);
|
|
|
+ public Control CreateContainer(object? item, int index, object? recycleKey)
|
|
|
+ => _owner.CreateContainerForItemOverride(item, index, recycleKey);
|
|
|
|
|
|
/// <summary>
|
|
|
/// Prepares the specified element as the container for the corresponding item.
|
|
@@ -84,10 +109,10 @@ namespace Avalonia.Controls.Generators
|
|
|
/// <param name="item">The item to display.</param>
|
|
|
/// <param name="index">The index of the item to display.</param>
|
|
|
/// <remarks>
|
|
|
- /// If <see cref="IsItemItsOwnContainer(Control)"/> is true for an item, then this method
|
|
|
- /// must only be called a single time, otherwise this method must be called after the
|
|
|
- /// container is created, and each subsequent time the container is recycled to display a
|
|
|
- /// new item.
|
|
|
+ /// If <see cref="NeedsContainer(object, int, out object?)"/> is false for an
|
|
|
+ /// item, then this method must only be called a single time; otherwise this method must
|
|
|
+ /// be called after the container is created, and each subsequent time the container is
|
|
|
+ /// recycled to display a new item.
|
|
|
/// </remarks>
|
|
|
public void PrepareItemContainer(Control container, object? item, int index) =>
|
|
|
_owner.PrepareItemContainer(container, item, index);
|
|
@@ -103,8 +128,8 @@ namespace Avalonia.Controls.Generators
|
|
|
/// This method must be called when a container has been fully prepared and added
|
|
|
/// to the logical and visual trees, but may be called before a layout pass has completed.
|
|
|
/// It must be called regardless of the result of
|
|
|
- /// <see cref="IsItemItsOwnContainer(Control)"/> but if that method returned true then
|
|
|
- /// must be called only a single time.
|
|
|
+ /// <see cref="NeedsContainer(object, int, out object?)"/> but if that method returned
|
|
|
+ /// false then must be called only a single time.
|
|
|
/// </remarks>
|
|
|
public void ItemContainerPrepared(Control container, object? item, int index) =>
|
|
|
_owner.ItemContainerPrepared(container, item, index);
|
|
@@ -127,7 +152,7 @@ namespace Avalonia.Controls.Generators
|
|
|
/// This method must be called when a container is unrealized. The container must have
|
|
|
/// already have been removed from the virtualizing panel's list of realized containers before
|
|
|
/// this method is called. This method must not be called if
|
|
|
- /// <see cref="IsItemItsOwnContainer"/> returned true for the item.
|
|
|
+ /// <see cref="NeedsContainer(object, int, out object?)"/> returned false for the item.
|
|
|
/// </remarks>
|
|
|
public void ClearItemContainer(Control container) => _owner.ClearItemContainer(container);
|
|
|
|