|
|
|
@ -1,5 +1,8 @@ |
|
|
|
using System; |
|
|
|
using Avalonia.Collections; |
|
|
|
using Avalonia.Controls.Presenters; |
|
|
|
using Avalonia.Controls.Templates; |
|
|
|
using Avalonia.Data; |
|
|
|
using Avalonia.LogicalTree; |
|
|
|
|
|
|
|
namespace Avalonia.Controls.Primitives |
|
|
|
@ -9,12 +12,21 @@ namespace Avalonia.Controls.Primitives |
|
|
|
/// </summary>
|
|
|
|
public class HeaderedSelectingItemsControl : SelectingItemsControl, IContentPresenterHost |
|
|
|
{ |
|
|
|
private IDisposable? _itemsBinding; |
|
|
|
private ItemsControl? _prepareItemContainerOnAttach; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="Header"/> property.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly StyledProperty<object?> HeaderProperty = |
|
|
|
HeaderedContentControl.HeaderProperty.AddOwner<HeaderedSelectingItemsControl>(); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="HeaderTemplate"/> property.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly StyledProperty<IDataTemplate?> HeaderTemplateProperty = |
|
|
|
HeaderedItemsControl.HeaderTemplateProperty.AddOwner<HeaderedSelectingItemsControl>(); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes static members of the <see cref="ContentControl"/> class.
|
|
|
|
/// </summary>
|
|
|
|
@ -32,6 +44,15 @@ namespace Avalonia.Controls.Primitives |
|
|
|
set { SetValue(HeaderProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the data template used to display the header content of the control.
|
|
|
|
/// </summary>
|
|
|
|
public IDataTemplate? HeaderTemplate |
|
|
|
{ |
|
|
|
get => GetValue(HeaderTemplateProperty); |
|
|
|
set => SetValue(HeaderTemplateProperty, value); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the header presenter from the control's template.
|
|
|
|
/// </summary>
|
|
|
|
@ -50,6 +71,17 @@ namespace Avalonia.Controls.Primitives |
|
|
|
return RegisterContentPresenter(presenter); |
|
|
|
} |
|
|
|
|
|
|
|
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) |
|
|
|
{ |
|
|
|
base.OnAttachedToLogicalTree(e); |
|
|
|
|
|
|
|
if (_prepareItemContainerOnAttach is not null) |
|
|
|
{ |
|
|
|
PrepareItemContainer(_prepareItemContainerOnAttach); |
|
|
|
_prepareItemContainerOnAttach = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called when an <see cref="IContentPresenter"/> is registered with the control.
|
|
|
|
/// </summary>
|
|
|
|
@ -65,6 +97,37 @@ namespace Avalonia.Controls.Primitives |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
internal void PrepareItemContainer(ItemsControl parent) |
|
|
|
{ |
|
|
|
_itemsBinding?.Dispose(); |
|
|
|
_itemsBinding = null; |
|
|
|
|
|
|
|
var item = Header; |
|
|
|
|
|
|
|
if (item is null) |
|
|
|
{ |
|
|
|
_prepareItemContainerOnAttach = null; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
var headerTemplate = HeaderTemplate ?? parent.ItemTemplate; |
|
|
|
|
|
|
|
if (headerTemplate is null) |
|
|
|
{ |
|
|
|
if (((ILogical)this).IsAttachedToLogicalTree) |
|
|
|
headerTemplate = this.FindDataTemplate(item); |
|
|
|
else |
|
|
|
_prepareItemContainerOnAttach = parent; |
|
|
|
} |
|
|
|
|
|
|
|
if (headerTemplate is ITreeDataTemplate treeTemplate && |
|
|
|
treeTemplate.Match(item) && |
|
|
|
treeTemplate.ItemsSelector(item) is { } itemsBinding) |
|
|
|
{ |
|
|
|
_itemsBinding = BindingOperations.Apply(this, ItemsSourceProperty, itemsBinding, null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void HeaderChanged(AvaloniaPropertyChangedEventArgs e) |
|
|
|
{ |
|
|
|
if (e.OldValue is ILogical oldChild) |
|
|
|
|