From 2b5d7fb28d88aa2c4399eb55a71a41ac74fd63d8 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 12 May 2020 13:34:03 +0200 Subject: [PATCH] Don't allow selection of non-expanded TreeViewItems. And remove child selection when a `TreeViewItem` is un-expanded. This is necessary because we don't get enough information about a materialized `TreeViewItem` to select it when materialized, so the `SelectionModel` and `TreeViewItem` selection state gets out of sync. --- src/Avalonia.Controls/TreeView.cs | 10 +++++++++- tests/Avalonia.Controls.UnitTests/TreeViewTests.cs | 13 +++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/TreeView.cs b/src/Avalonia.Controls/TreeView.cs index 165276c539..a55274afb3 100644 --- a/src/Avalonia.Controls/TreeView.cs +++ b/src/Avalonia.Controls/TreeView.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Reactive.Linq; using Avalonia.Controls.Generators; using Avalonia.Controls.Primitives; using Avalonia.Controls.Utils; @@ -395,7 +396,14 @@ namespace Avalonia.Controls private void OnSelectionModelChildrenRequested(object sender, SelectionModelChildrenRequestedEventArgs e) { var container = ItemContainerGenerator.Index.ContainerFromItem(e.Source) as ItemsControl; - e.Children = container?.GetObservable(ItemsProperty); + + if (container is object) + { + e.Children = Observable.CombineLatest( + container.GetObservable(TreeViewItem.IsExpandedProperty), + container.GetObservable(ItemsProperty), + (expanded, items) => expanded ? items : null); + } } private TreeViewItem GetContainerInDirection( diff --git a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs index 1563df5aae..373f3e6861 100644 --- a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs @@ -130,6 +130,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var item = tree[0].Children[1].Children[0]; var container = (TreeViewItem)target.ItemContainerGenerator.Index.ContainerFromItem(item); @@ -157,6 +158,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var item = tree[0].Children[1].Children[0]; var container = (TreeViewItem)target.ItemContainerGenerator.Index.ContainerFromItem(item); @@ -188,6 +190,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var item1 = tree[0].Children[1].Children[0]; var container1 = (TreeViewItem)target.ItemContainerGenerator.Index.ContainerFromItem(item1); @@ -225,6 +228,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var rootNode = tree[0]; @@ -264,6 +268,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var rootNode = tree[0]; @@ -297,6 +302,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var rootNode = tree[0]; @@ -330,6 +336,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var rootNode = tree[0]; @@ -376,6 +383,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var item = tree[0].Children[1].Children[0]; var container = (TreeViewItem)target.ItemContainerGenerator.Index.ContainerFromItem(item); @@ -402,6 +410,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var item = tree[0].Children[1].Children[0]; @@ -579,6 +588,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var item = data[0].Children[0]; var node = target.ItemContainerGenerator.Index.ContainerFromItem(item); @@ -614,6 +624,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var rootNode = tree[0]; @@ -651,6 +662,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var rootNode = tree[0]; @@ -697,6 +709,7 @@ namespace Avalonia.Controls.UnitTests CreateNodeDataTemplate(target); ApplyTemplates(target); + ExpandAll(target); var rootNode = tree[0];