Explorar o código

Make ItemTemplate work for TreeView.

Steven Kirk %!s(int64=9) %!d(string=hai) anos
pai
achega
57a0122549

+ 3 - 3
src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs

@@ -75,7 +75,7 @@ namespace Avalonia.Controls.Generators
             }
             else
             {
-                var template = GetTreeDataTemplate(item);
+                var template = GetTreeDataTemplate(item, ItemTemplate);
                 var result = new T();
 
                 result.SetValue(ContentProperty, template.Build(item));
@@ -123,9 +123,9 @@ namespace Avalonia.Controls.Generators
         /// </summary>
         /// <param name="item">The item.</param>
         /// <returns>The template.</returns>
-        private ITreeDataTemplate GetTreeDataTemplate(object item)
+        private ITreeDataTemplate GetTreeDataTemplate(object item, IDataTemplate primary)
         {
-            var template = Owner.FindDataTemplate(item) ?? FuncDataTemplate.Default;
+            var template = Owner.FindDataTemplate(item, primary) ?? FuncDataTemplate.Default;
             var treeTemplate = template as ITreeDataTemplate ??
                 new FuncTreeDataTemplate(typeof(object), template.Build, x => null);
             return treeTemplate;

+ 1 - 1
src/Avalonia.Controls/TreeView.cs

@@ -96,7 +96,7 @@ namespace Avalonia.Controls
             var result = new TreeItemContainerGenerator<TreeViewItem>(
                 this,
                 TreeViewItem.HeaderProperty,
-                null,
+                TreeViewItem.ItemTemplateProperty,
                 TreeViewItem.ItemsProperty,
                 TreeViewItem.IsExpandedProperty,
                 new TreeContainerIndex());

+ 6 - 1
src/Avalonia.Controls/TreeViewItem.cs

@@ -80,7 +80,7 @@ namespace Avalonia.Controls
             return new TreeItemContainerGenerator<TreeViewItem>(
                 this,
                 TreeViewItem.HeaderProperty,
-                null,
+                TreeViewItem.ItemTemplateProperty,
                 TreeViewItem.ItemsProperty,
                 TreeViewItem.IsExpandedProperty,
                 _treeView?.ItemContainerGenerator.Index ?? new TreeContainerIndex());
@@ -91,6 +91,11 @@ namespace Avalonia.Controls
         {
             base.OnAttachedToLogicalTree(e);
             _treeView = this.GetLogicalAncestors().OfType<TreeView>().FirstOrDefault();
+
+            if (ItemTemplate == null && _treeView?.ItemTemplate != null)
+            {
+                ItemTemplate = _treeView.ItemTemplate;
+            }
         }
 
         protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)

+ 42 - 3
tests/Avalonia.Controls.UnitTests/TreeViewTests.cs

@@ -35,6 +35,33 @@ namespace Avalonia.Controls.UnitTests
             Assert.Equal(new[] { "Grandchild2a" }, ExtractItemHeader(target, 2));
         }
 
+        [Fact]
+        public void Items_Should_Be_Created_Using_ItemTemplate_If_Present()
+        {
+            TreeView target;
+
+            var root = new TestRoot
+            {
+                Child = target = new TreeView
+                {
+                    Template = CreateTreeViewTemplate(),
+                    Items = CreateTestTreeData(),
+                    ItemTemplate = new FuncTreeDataTemplate<Node>(
+                        _ => new Canvas(),
+                        x => x.Children),
+                }
+            };
+
+            ApplyTemplates(target);
+
+            var items = target.ItemContainerGenerator.Index.Items
+                .OfType<TreeViewItem>()
+                .ToList();
+
+            Assert.Equal(4, items.Count);
+            Assert.All(items, x => Assert.IsType<Canvas>(x.HeaderPresenter.Child));
+        }
+
         [Fact]
         public void Root_ItemContainerGenerator_Containers_Should_Be_Root_Containers()
         {
@@ -302,6 +329,7 @@ namespace Avalonia.Controls.UnitTests
                 control.Template = CreateTreeViewItemTemplate();
                 control.ApplyTemplate();
                 control.Presenter.ApplyTemplate();
+                control.HeaderPresenter.ApplyTemplate();
                 ApplyTemplates(control.Presenter.Panel.Children);
             }
         }
@@ -354,10 +382,21 @@ namespace Avalonia.Controls.UnitTests
 
         private IControlTemplate CreateTreeViewItemTemplate()
         {
-            return new FuncControlTemplate<TreeViewItem>(parent => new ItemsPresenter
+            return new FuncControlTemplate<TreeViewItem>(parent => new Panel
             {
-                Name = "PART_ItemsPresenter",
-                [~ItemsPresenter.ItemsProperty] = parent[~ItemsControl.ItemsProperty],
+                Children = new Controls
+                {
+                    new ContentPresenter
+                    {
+                        Name = "PART_HeaderPresenter",
+                        [~ContentPresenter.ContentProperty] = parent[~TreeViewItem.HeaderProperty],
+                    },
+                    new ItemsPresenter
+                    {
+                        Name = "PART_ItemsPresenter",
+                        [~ItemsPresenter.ItemsProperty] = parent[~ItemsControl.ItemsProperty],
+                    }
+                }
             });
         }