Browse Source

Search for data template on tree attachment.

When a `HeaderedItemsControl` is used in an `ItemsControl` it needs to search for an `ITreeDataTemplate` in order to populate the `Items` property. This can't be done properly until it's attached to the logical tree.

Fixes #10398
pull/10511/head
Steven Kirk 4 years ago
parent
commit
5281bbcca0
  1. 9
      src/Avalonia.Controls/ItemsControl.cs
  2. 47
      src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs

9
src/Avalonia.Controls/ItemsControl.cs

@ -383,14 +383,7 @@ namespace Avalonia.Controls
{
hic.Header = item;
hic.HeaderTemplate = itemTemplate;
itemTemplate ??= hic.FindDataTemplate(item) ?? this.FindDataTemplate(item);
if (itemTemplate is ITreeDataTemplate treeTemplate)
{
if (item is not null && treeTemplate.ItemsSelector(item) is { } itemsBinding)
BindingOperations.Apply(hic, ItemsProperty, itemsBinding, null);
}
hic.PrepareItemContainer();
}
}

47
src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs

@ -1,6 +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
@ -10,6 +12,9 @@ namespace Avalonia.Controls.Primitives
/// </summary>
public class HeaderedItemsControl : ItemsControl, IContentPresenterHost
{
private IDisposable? _itemsBinding;
private bool _prepareItemContainerOnAttach;
/// <summary>
/// Defines the <see cref="Header"/> property.
/// </summary>
@ -60,6 +65,17 @@ namespace Avalonia.Controls.Primitives
/// <inheritdoc/>
IAvaloniaList<ILogical> IContentPresenterHost.LogicalChildren => LogicalChildren;
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
if (_prepareItemContainerOnAttach)
{
PrepareItemContainer();
_prepareItemContainerOnAttach = false;
}
}
/// <inheritdoc/>
bool IContentPresenterHost.RegisterContentPresenter(IContentPresenter presenter)
{
@ -81,6 +97,37 @@ namespace Avalonia.Controls.Primitives
return false;
}
internal void PrepareItemContainer()
{
_itemsBinding?.Dispose();
_itemsBinding = null;
var item = Header;
if (item is null)
{
_prepareItemContainerOnAttach = false;
return;
}
var headerTemplate = HeaderTemplate;
if (headerTemplate is null)
{
if (((ILogical)this).IsAttachedToLogicalTree)
headerTemplate = this.FindDataTemplate(item);
else
_prepareItemContainerOnAttach = true;
}
if (headerTemplate is ITreeDataTemplate treeTemplate &&
treeTemplate.Match(item) &&
treeTemplate.ItemsSelector(item) is { } itemsBinding)
{
_itemsBinding = BindingOperations.Apply(this, ItemsProperty, itemsBinding, null);
}
}
private void HeaderChanged(AvaloniaPropertyChangedEventArgs e)
{
if (e.OldValue is ILogical oldChild)

Loading…
Cancel
Save