Skip to content

Commit dc37697

Browse files
authored
Fixing TreeListView to work with non-generic collections (#3356)
Specifically ICollectionView
1 parent 44bb9ba commit dc37697

File tree

7 files changed

+123
-39
lines changed

7 files changed

+123
-39
lines changed

MaterialDesignThemes.UITests/WPF/TreeListViews/TreeListViewTemplateSelector.xaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:local="clr-namespace:MaterialDesignThemes.UITests.WPF.TreeListViews"
77
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
8-
xmlns:sys="clr-namespace:System;assembly=mscorlib"
98
mc:Ignorable="d"
109
DataContext="{Binding RelativeSource={RelativeSource Self}}"
1110
d:DesignHeight="450" d:DesignWidth="800">

MaterialDesignThemes.UITests/WPF/TreeListViews/TreeListViewTests.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,35 @@ public async Task TreeListView_WithTemplateSelector_UsesSelectorTemplates()
956956
recorder.Success();
957957
}
958958

959+
[Fact]
960+
public async Task TreeListView_WithCollectionView_RendersItems()
961+
{
962+
await using var recorder = new TestRecorder(App);
963+
964+
IVisualElement<TreeListView> treeListView = (await LoadUserControl<TreeListViewWithCollectionView>()).As<TreeListView>();
965+
966+
IVisualElement<TreeListViewItem> item3 = await treeListView.GetElement<TreeListViewItem>("/TreeListViewItem[2]");
967+
IVisualElement<TreeListViewItem> item4 = await treeListView.GetElement<TreeListViewItem>("/TreeListViewItem[3]");
968+
969+
await item3.LeftClickExpander();
970+
await Task.Delay(500);
971+
await item4.LeftClickExpander();
972+
await Task.Delay(500);
973+
974+
await AssertTreeItemContent(treeListView, 0, "Foo");
975+
await AssertTreeItemContent(treeListView, 1, "42");
976+
await AssertTreeItemContent(treeListView, 2, "24", true);
977+
await AssertTreeItemContent(treeListView, 3, "a");
978+
await AssertTreeItemContent(treeListView, 4, "b");
979+
await AssertTreeItemContent(treeListView, 5, "c");
980+
await AssertTreeItemContent(treeListView, 6, "Bar", true);
981+
await AssertTreeItemContent(treeListView, 7, "1");
982+
await AssertTreeItemContent(treeListView, 8, "2");
983+
await AssertTreeItemContent(treeListView, 9, "3");
984+
985+
recorder.Success();
986+
}
987+
959988
private static async Task AssertTreeItemContent(IVisualElement<TreeListView> treeListView, int index, string content, bool isExpanded = false)
960989
{
961990
await Wait.For(async () =>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<UserControl x:Class="MaterialDesignThemes.UITests.WPF.TreeListViews.TreeListViewWithCollectionView"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:local="clr-namespace:MaterialDesignThemes.UITests.WPF.TreeListViews"
6+
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
7+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8+
d:DesignHeight="450"
9+
d:DesignWidth="800"
10+
DataContext="{Binding RelativeSource={RelativeSource Self}}"
11+
mc:Ignorable="d">
12+
<materialDesign:TreeListView ItemsSource="{Binding Items}">
13+
<materialDesign:TreeListView.Resources>
14+
<HierarchicalDataTemplate DataType="{x:Type local:TreeItem}" ItemsSource="{Binding Children}">
15+
<TextBlock Text="{Binding Value}" />
16+
</HierarchicalDataTemplate>
17+
</materialDesign:TreeListView.Resources>
18+
</materialDesign:TreeListView>
19+
</UserControl>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Collections.ObjectModel;
2+
using System.ComponentModel;
3+
using System.Windows.Data;
4+
5+
namespace MaterialDesignThemes.UITests.WPF.TreeListViews;
6+
7+
/// <summary>
8+
/// Interaction logic for TreeListViewWithCollectionView.xaml
9+
/// </summary>
10+
public partial class TreeListViewWithCollectionView : UserControl
11+
{
12+
private ObservableCollection<TreeItem> ItemsSource { get; } = new();
13+
14+
public ICollectionView Items { get; }
15+
16+
public TreeListViewWithCollectionView()
17+
{
18+
Items = CollectionViewSource.GetDefaultView(ItemsSource);
19+
20+
InitializeComponent();
21+
22+
AddChildren("Foo");
23+
AddChildren("42");
24+
AddChildren("24", "a", "b", "c");
25+
AddChildren("Bar", "1", "2", "3");
26+
27+
void AddChildren(string root, params string[] children)
28+
{
29+
TreeItem item = new(root, null);
30+
foreach (string child in children)
31+
{
32+
item.Children.Add(new TreeItem(child, item));
33+
}
34+
ItemsSource.Add(item);
35+
}
36+
}
37+
}

MaterialDesignThemes.Wpf.Tests/Internal/TreeListViewItemsCollectionTests.cs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ public class TreeListViewItemsCollectionTests
1010
[Fact]
1111
public void Constructor_AcceptsNull()
1212
{
13-
TreeListViewItemsCollection<string> collection = new(null);
13+
TreeListViewItemsCollection collection = new(null);
1414

1515
Assert.Empty(collection);
1616
}
1717

1818
[Fact]
1919
public void Constructor_AcceptsObject()
2020
{
21-
TreeListViewItemsCollection<string> collection = new(new object());
21+
TreeListViewItemsCollection collection = new(new object());
2222

2323
Assert.Empty(collection);
2424
}
@@ -27,7 +27,7 @@ public void Constructor_AcceptsObject()
2727
public void Constructor_AcceptsIEnumerable()
2828
{
2929
IEnumerable<string> enumerable = new[] { "a", "b", "c" };
30-
TreeListViewItemsCollection<string> collection = new(enumerable);
30+
TreeListViewItemsCollection collection = new(enumerable);
3131

3232
Assert.Equal(new[] { "a", "b", "c" }, collection);
3333
}
@@ -38,7 +38,7 @@ public void WhenWrappedObjectImplementsIncc_ItHandlesAdditions()
3838
//Arrange
3939
ObservableCollection<string> collection = new();
4040

41-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
41+
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);
4242

4343
//Act
4444
collection.Add("a");
@@ -53,7 +53,7 @@ public void WhenWrappedObjectImplementsIncc_ItHandlesRemovals()
5353
//Arrange
5454
ObservableCollection<string> collection = new() { "a" };
5555

56-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
56+
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);
5757

5858
//Act
5959
collection.Remove("a");
@@ -68,7 +68,7 @@ public void WhenWrappedObjectImplementsIncc_ItHandlesReplacements()
6868
//Arrange
6969
ObservableCollection<string> collection = new() { "a", "b", "c" };
7070

71-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
71+
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);
7272

7373
// Simulate expansion
7474
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
@@ -98,7 +98,7 @@ public void WhenWrappedObjectImplementsIncc_ItHandlesReset()
9898
//Arrange
9999
TestableCollection<string> collection = new() { "a" };
100100

101-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
101+
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);
102102

103103
//Act
104104
collection.ReplaceAllItems("b", "c");
@@ -113,7 +113,7 @@ public void WhenWrappedObjectImplementsIncc_ItHandlesMoves()
113113
//Arrange
114114
ObservableCollection<string> collection = new() { "a", "b", "c" };
115115

116-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
116+
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);
117117

118118
//Act
119119
collection.Move(0, 2);
@@ -134,7 +134,7 @@ public void WhenWrappedObjectImplementsIncc_ItHandlesMoves()
134134
public void WhenAddingItemAtNestedLevel_ItSetsTheItemsLevel(int insertionIndex, int requestedLevel)
135135
{
136136
//Arrange
137-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b" });
137+
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b" });
138138
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
139139
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
140140
/*
@@ -167,7 +167,7 @@ public void WhenAddingItemAtNestedLevel_ItSetsTheItemsLevel(int insertionIndex,
167167
public void InsertWithLevel_WhenAddingItemAtNestedLevel_ItThrowsIfRequestIsOutOfRange(int insertionIndex, int requestedLevel)
168168
{
169169
//Arrange
170-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b" });
170+
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b" });
171171
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
172172
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
173173
/*
@@ -184,7 +184,7 @@ public void InsertWithLevel_WhenAddingItemAtNestedLevel_ItThrowsIfRequestIsOutOf
184184
[Fact]
185185
public void InsertWithLevel_WhenInsertingFirstSibling_MarksIndexAsExpanded()
186186
{
187-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b" });
187+
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b" });
188188

189189
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
190190
/*
@@ -203,7 +203,7 @@ public void InsertWithLevel_WhenInsertingFirstSibling_MarksIndexAsExpanded()
203203
public void WhenRemovingItem_ItRemovesItemsAndAnyChildren(int indexToRemove, string[] expectedItems, int[] expectedLevels)
204204
{
205205
//Arrange
206-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
206+
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
207207
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
208208
treeListViewItemsCollection.InsertWithLevel(2, "a_a_a", 2);
209209
treeListViewItemsCollection.InsertWithLevel(3, "a_a_b", 2);
@@ -231,7 +231,7 @@ public void WhenRemovingItem_ItRemovesItemsAndAnyChildren(int indexToRemove, str
231231
public void Move_WhenMovingItemUp_ItMovesChildrenAlongWithIt()
232232
{
233233
//Arrange
234-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
234+
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
235235
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
236236
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
237237
treeListViewItemsCollection.InsertWithLevel(4, "b_a", 1);
@@ -267,7 +267,7 @@ public void Move_WhenMovingItemUp_ItMovesChildrenAlongWithIt()
267267
public void Move_WhenMovingItemUpMultipleLevels_ItMovesChildrenAlongWithIt()
268268
{
269269
//Arrange
270-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
270+
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
271271
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
272272
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
273273
treeListViewItemsCollection.InsertWithLevel(4, "b_a", 1);
@@ -301,7 +301,7 @@ public void Move_WhenMovingItemUpMultipleLevels_ItMovesChildrenAlongWithIt()
301301
public void Move_WhenMovingItemDown_ItMovesChildrenAlongWithIt()
302302
{
303303
//Arrange
304-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
304+
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
305305
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
306306
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
307307
treeListViewItemsCollection.InsertWithLevel(4, "b_a", 1);
@@ -337,7 +337,7 @@ public void Move_WhenMovingItemDown_ItMovesChildrenAlongWithIt()
337337
public void Move_WhenMovingItemDownMultipleLevels_ItMovesChildrenAlongWithIt()
338338
{
339339
//Arrange
340-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
340+
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
341341
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
342342
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
343343
treeListViewItemsCollection.InsertWithLevel(4, "b_a", 1);
@@ -372,7 +372,7 @@ public void Move_WithWrappedCollection_ItMovesChildrenAlongWithIt()
372372
{
373373
//Arrange
374374
ObservableCollection<string> boundCollection = new() { "a", "b", "c" };
375-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
375+
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
376376
treeListViewItemsCollection.InsertWithLevel(2, "b_a", 1);
377377
treeListViewItemsCollection.InsertWithLevel(3, "b_b", 1);
378378
treeListViewItemsCollection.InsertWithLevel(4, "b_c", 1);
@@ -401,7 +401,7 @@ public void Move_WithExpandedChild_ItMovesChildrenUp()
401401
{
402402
//Arrange
403403
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
404-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
404+
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
405405
treeListViewItemsCollection.InsertWithLevel(2, "1_0", 1);
406406
treeListViewItemsCollection.InsertWithLevel(3, "1_1", 1);
407407
treeListViewItemsCollection.InsertWithLevel(4, "1_1_0", 2);
@@ -459,7 +459,7 @@ public void Move_WithExpandedChild_ItMovesChildrenDown()
459459
{
460460
//Arrange
461461
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
462-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
462+
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
463463
treeListViewItemsCollection.InsertWithLevel(1, "0_0", 1);
464464
treeListViewItemsCollection.InsertWithLevel(2, "0_1", 1);
465465
treeListViewItemsCollection.InsertWithLevel(3, "0_1_0", 2);
@@ -517,7 +517,7 @@ public void Replace_WithExpandedChild_ItRemovesChildren()
517517
{
518518
//Arrange
519519
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
520-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
520+
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
521521
treeListViewItemsCollection.InsertWithLevel(3, "2_0", 1);
522522
treeListViewItemsCollection.InsertWithLevel(4, "2_1", 1);
523523
treeListViewItemsCollection.InsertWithLevel(5, "2_2", 1);
@@ -560,7 +560,7 @@ public void Replace_TopLevelItem_IsReplaced(int indexToReplace)
560560
{
561561
//Arrange
562562
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
563-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
563+
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
564564

565565
/*
566566
* 0. 0
@@ -598,7 +598,7 @@ public void GetParent_WithInvalidIndex_ThrowsOutOfRangeException(int index)
598598
{
599599
//Arrange
600600
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
601-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
601+
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
602602

603603
//Act/Assert
604604
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => treeListViewItemsCollection.GetParent(index));
@@ -610,7 +610,7 @@ public void GetParent_WithNestedItem_ReturnsParent()
610610
{
611611
//Arrange
612612
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
613-
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
613+
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
614614
treeListViewItemsCollection.InsertWithLevel(2, "1_0", 1);
615615
treeListViewItemsCollection.InsertWithLevel(3, "1_1", 1);
616616
treeListViewItemsCollection.InsertWithLevel(4, "1_2", 1);
@@ -674,15 +674,15 @@ public void ReplaceAllItems(params T[] newItems)
674674

675675
public static class TreeListViewItemsCollectionExtensions
676676
{
677-
public static IEnumerable<int> GetAllLevels<T>(this TreeListViewItemsCollection<T> collection)
677+
public static IEnumerable<int> GetAllLevels(this TreeListViewItemsCollection collection)
678678
{
679679
for (int i = 0; i < collection.Count; i++)
680680
{
681681
yield return collection.GetLevel(i);
682682
}
683683
}
684684

685-
public static IEnumerable<bool> GetAllIsExpanded<T>(this TreeListViewItemsCollection<T> collection)
685+
public static IEnumerable<bool> GetAllIsExpanded(this TreeListViewItemsCollection collection)
686686
{
687687
for (int i = 0; i < collection.Count; i++)
688688
{

0 commit comments

Comments
 (0)