diff --git a/src/Avalonia.Controls/TreeView.cs b/src/Avalonia.Controls/TreeView.cs
index 8f2636a783..1a9042a25b 100644
--- a/src/Avalonia.Controls/TreeView.cs
+++ b/src/Avalonia.Controls/TreeView.cs
@@ -10,6 +10,7 @@ using Avalonia.Controls.Generators;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Input.Platform;
+using Avalonia.Layout;
using Avalonia.Threading;
using Avalonia.VisualTree;
@@ -163,6 +164,9 @@ namespace Avalonia.Controls
{
item.IsExpanded = true;
+ if (item.Presenter?.Panel is null)
+ (this.GetVisualRoot() as ILayoutRoot)?.LayoutManager.ExecuteLayoutPass();
+
if (item.Presenter?.Panel is { } panel)
{
foreach (var child in panel.Children)
diff --git a/src/Avalonia.Controls/TreeViewItem.cs b/src/Avalonia.Controls/TreeViewItem.cs
index cf83ba8253..5dbfe49533 100644
--- a/src/Avalonia.Controls/TreeViewItem.cs
+++ b/src/Avalonia.Controls/TreeViewItem.cs
@@ -90,8 +90,20 @@ namespace Avalonia.Controls
internal TreeView? TreeViewOwner => _treeView;
- protected internal override Control CreateContainerForItemOverride() => new TreeViewItem();
- protected internal override bool IsItemItsOwnContainerOverride(Control item) => item is TreeViewItem;
+ protected internal override Control CreateContainerForItemOverride()
+ {
+ return EnsureTreeView().CreateContainerForItemOverride();
+ }
+
+ protected internal override bool IsItemItsOwnContainerOverride(Control item)
+ {
+ return EnsureTreeView().IsItemItsOwnContainerOverride(item);
+ }
+
+ protected internal override void PrepareContainerForItemOverride(Control container, object? item, int index)
+ {
+ EnsureTreeView().PrepareContainerForItemOverride(container, item, index);
+ }
///
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
@@ -283,6 +295,9 @@ namespace Avalonia.Controls
return logical != null ? result : @default;
}
+ private TreeView EnsureTreeView() => _treeView ??
+ throw new InvalidOperationException("The TreeViewItem is not part of a TreeView.");
+
private void HeaderDoubleTapped(object? sender, TappedEventArgs e)
{
OnHeaderDoubleTapped(e);
diff --git a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs
index 4f533c2f78..129720d00a 100644
--- a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs
@@ -1,43 +1,35 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using Avalonia.Collections;
-using Avalonia.Controls.Generators;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Data.Core;
using Avalonia.Input;
using Avalonia.Input.Platform;
-using Avalonia.Interactivity;
+using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.Styling;
using Avalonia.UnitTests;
-using Moq;
+using Avalonia.VisualTree;
using Xunit;
+#nullable enable
+
namespace Avalonia.Controls.UnitTests
{
public class TreeViewTests
{
- MouseTestHelper _mouse = new MouseTestHelper();
+ private readonly MouseTestHelper _mouse = new();
[Fact]
public void Items_Should_Be_Created()
{
- var target = new TreeView
- {
- Template = CreateTreeViewTemplate(),
- ItemsSource = CreateTestTreeData(),
- };
-
- var root = new TestRoot(target);
-
- CreateNodeDataTemplate(target);
- ApplyTemplates(target);
+ using var app = Start();
+ var target = CreateTarget();
Assert.Equal(new[] { "Root" }, ExtractItemHeader(target, 0));
Assert.Equal(new[] { "Child1", "Child2", "Child3" }, ExtractItemHeader(target, 1));
@@ -47,50 +39,31 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Items_Should_Be_Created_Using_ItemTemplate_If_Present()
{
- TreeView target;
-
- var root = new TestRoot
- {
- Child = target = new TreeView
- {
- Template = CreateTreeViewTemplate(),
- ItemsSource = CreateTestTreeData(),
- ItemTemplate = new FuncTreeDataTemplate(
- (_, __) => new Canvas(),
- x => x.Children),
- }
- };
-
- ApplyTemplates(target);
+ using var app = Start();
+ var itemTemplate = new FuncTreeDataTemplate(
+ (_, _) => new Canvas(),
+ x => x.Children);
+ var target = CreateTarget(itemTemplate: itemTemplate);
var items = target.GetRealizedTreeContainers()
.OfType()
.ToList();
Assert.Equal(5, items.Count);
- Assert.All(items, x => Assert.IsType