@ -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 )