Skip to content

Commit

Permalink
Fixing TreeListView to work with non-generic collections
Browse files Browse the repository at this point in the history
Specifically ICollectionView
  • Loading branch information
Keboo committed Nov 2, 2023
1 parent 44bb9ba commit 9c8ff77
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MaterialDesignThemes.UITests.WPF.TreeListViews"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="450" d:DesignWidth="800">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,35 @@ public async Task TreeListView_WithTemplateSelector_UsesSelectorTemplates()
recorder.Success();
}

[Fact]
public async Task TreeListView_WithCollectionView_RendersItems()
{
await using var recorder = new TestRecorder(App);

IVisualElement<TreeListView> treeListView = (await LoadUserControl<TreeListViewWithCollectionView>()).As<TreeListView>();

IVisualElement<TreeListViewItem> item3 = await treeListView.GetElement<TreeListViewItem>("/TreeListViewItem[2]");
IVisualElement<TreeListViewItem> item4 = await treeListView.GetElement<TreeListViewItem>("/TreeListViewItem[3]");

await item3.LeftClickExpander();
await Task.Delay(500);
await item4.LeftClickExpander();
await Task.Delay(500);

await AssertTreeItemContent(treeListView, 0, "Foo");
await AssertTreeItemContent(treeListView, 1, "42");
await AssertTreeItemContent(treeListView, 2, "24", true);
await AssertTreeItemContent(treeListView, 3, "a");
await AssertTreeItemContent(treeListView, 4, "b");
await AssertTreeItemContent(treeListView, 5, "c");
await AssertTreeItemContent(treeListView, 6, "Bar", true);
await AssertTreeItemContent(treeListView, 7, "1");
await AssertTreeItemContent(treeListView, 8, "2");
await AssertTreeItemContent(treeListView, 9, "3");

recorder.Success();
}

private static async Task AssertTreeItemContent(IVisualElement<TreeListView> treeListView, int index, string content, bool isExpanded = false)
{
await Wait.For(async () =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<UserControl x:Class="MaterialDesignThemes.UITests.WPF.TreeListViews.TreeListViewWithCollectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MaterialDesignThemes.UITests.WPF.TreeListViews"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
<materialDesign:TreeListView ItemsSource="{Binding Items}">
<materialDesign:TreeListView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:TreeItem}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Value}" />
</HierarchicalDataTemplate>
</materialDesign:TreeListView.Resources>
</materialDesign:TreeListView>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;

namespace MaterialDesignThemes.UITests.WPF.TreeListViews;

/// <summary>
/// Interaction logic for TreeListViewWithCollectionView.xaml
/// </summary>
public partial class TreeListViewWithCollectionView : UserControl
{
private ObservableCollection<TreeItem> ItemsSource { get; } = new();

public ICollectionView Items { get; }

public TreeListViewWithCollectionView()
{
Items = CollectionViewSource.GetDefaultView(ItemsSource);

InitializeComponent();

AddChildren("Foo");
AddChildren("42");
AddChildren("24", "a", "b", "c");
AddChildren("Bar", "1", "2", "3");

void AddChildren(string root, params string[] children)
{
TreeItem item = new(root, null);
foreach (string child in children)
{
item.Children.Add(new TreeItem(child, item));
}
ItemsSource.Add(item);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ public class TreeListViewItemsCollectionTests
[Fact]
public void Constructor_AcceptsNull()
{
TreeListViewItemsCollection<string> collection = new(null);
TreeListViewItemsCollection collection = new(null);

Assert.Empty(collection);
}

[Fact]
public void Constructor_AcceptsObject()
{
TreeListViewItemsCollection<string> collection = new(new object());
TreeListViewItemsCollection collection = new(new object());

Assert.Empty(collection);
}
Expand All @@ -27,7 +27,7 @@ public void Constructor_AcceptsObject()
public void Constructor_AcceptsIEnumerable()
{
IEnumerable<string> enumerable = new[] { "a", "b", "c" };
TreeListViewItemsCollection<string> collection = new(enumerable);
TreeListViewItemsCollection collection = new(enumerable);

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

TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);

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

TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);

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

TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);

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

TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);

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

TreeListViewItemsCollection<string> treeListViewItemsCollection = new(collection);
TreeListViewItemsCollection treeListViewItemsCollection = new(collection);

//Act
collection.Move(0, 2);
Expand All @@ -134,7 +134,7 @@ public void WhenWrappedObjectImplementsIncc_ItHandlesMoves()
public void WhenAddingItemAtNestedLevel_ItSetsTheItemsLevel(int insertionIndex, int requestedLevel)
{
//Arrange
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b" });
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b" });
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
/*
Expand Down Expand Up @@ -167,7 +167,7 @@ public void WhenAddingItemAtNestedLevel_ItSetsTheItemsLevel(int insertionIndex,
public void InsertWithLevel_WhenAddingItemAtNestedLevel_ItThrowsIfRequestIsOutOfRange(int insertionIndex, int requestedLevel)
{
//Arrange
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b" });
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b" });
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
/*
Expand All @@ -184,7 +184,7 @@ public void InsertWithLevel_WhenAddingItemAtNestedLevel_ItThrowsIfRequestIsOutOf
[Fact]
public void InsertWithLevel_WhenInsertingFirstSibling_MarksIndexAsExpanded()
{
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b" });
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b" });

treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
/*
Expand All @@ -203,7 +203,7 @@ public void InsertWithLevel_WhenInsertingFirstSibling_MarksIndexAsExpanded()
public void WhenRemovingItem_ItRemovesItemsAndAnyChildren(int indexToRemove, string[] expectedItems, int[] expectedLevels)
{
//Arrange
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
treeListViewItemsCollection.InsertWithLevel(2, "a_a_a", 2);
treeListViewItemsCollection.InsertWithLevel(3, "a_a_b", 2);
Expand Down Expand Up @@ -231,7 +231,7 @@ public void WhenRemovingItem_ItRemovesItemsAndAnyChildren(int indexToRemove, str
public void Move_WhenMovingItemUp_ItMovesChildrenAlongWithIt()
{
//Arrange
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
treeListViewItemsCollection.InsertWithLevel(4, "b_a", 1);
Expand Down Expand Up @@ -267,7 +267,7 @@ public void Move_WhenMovingItemUp_ItMovesChildrenAlongWithIt()
public void Move_WhenMovingItemUpMultipleLevels_ItMovesChildrenAlongWithIt()
{
//Arrange
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
treeListViewItemsCollection.InsertWithLevel(4, "b_a", 1);
Expand Down Expand Up @@ -301,7 +301,7 @@ public void Move_WhenMovingItemUpMultipleLevels_ItMovesChildrenAlongWithIt()
public void Move_WhenMovingItemDown_ItMovesChildrenAlongWithIt()
{
//Arrange
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
treeListViewItemsCollection.InsertWithLevel(4, "b_a", 1);
Expand Down Expand Up @@ -337,7 +337,7 @@ public void Move_WhenMovingItemDown_ItMovesChildrenAlongWithIt()
public void Move_WhenMovingItemDownMultipleLevels_ItMovesChildrenAlongWithIt()
{
//Arrange
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(new[] { "a", "b", "c" });
TreeListViewItemsCollection treeListViewItemsCollection = new(new[] { "a", "b", "c" });
treeListViewItemsCollection.InsertWithLevel(1, "a_a", 1);
treeListViewItemsCollection.InsertWithLevel(2, "a_b", 1);
treeListViewItemsCollection.InsertWithLevel(4, "b_a", 1);
Expand Down Expand Up @@ -372,7 +372,7 @@ public void Move_WithWrappedCollection_ItMovesChildrenAlongWithIt()
{
//Arrange
ObservableCollection<string> boundCollection = new() { "a", "b", "c" };
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
treeListViewItemsCollection.InsertWithLevel(2, "b_a", 1);
treeListViewItemsCollection.InsertWithLevel(3, "b_b", 1);
treeListViewItemsCollection.InsertWithLevel(4, "b_c", 1);
Expand Down Expand Up @@ -401,7 +401,7 @@ public void Move_WithExpandedChild_ItMovesChildrenUp()
{
//Arrange
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
treeListViewItemsCollection.InsertWithLevel(2, "1_0", 1);
treeListViewItemsCollection.InsertWithLevel(3, "1_1", 1);
treeListViewItemsCollection.InsertWithLevel(4, "1_1_0", 2);
Expand Down Expand Up @@ -459,7 +459,7 @@ public void Move_WithExpandedChild_ItMovesChildrenDown()
{
//Arrange
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
treeListViewItemsCollection.InsertWithLevel(1, "0_0", 1);
treeListViewItemsCollection.InsertWithLevel(2, "0_1", 1);
treeListViewItemsCollection.InsertWithLevel(3, "0_1_0", 2);
Expand Down Expand Up @@ -517,7 +517,7 @@ public void Replace_WithExpandedChild_ItRemovesChildren()
{
//Arrange
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
treeListViewItemsCollection.InsertWithLevel(3, "2_0", 1);
treeListViewItemsCollection.InsertWithLevel(4, "2_1", 1);
treeListViewItemsCollection.InsertWithLevel(5, "2_2", 1);
Expand Down Expand Up @@ -560,7 +560,7 @@ public void Replace_TopLevelItem_IsReplaced(int indexToReplace)
{
//Arrange
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);

/*
* 0. 0
Expand Down Expand Up @@ -598,7 +598,7 @@ public void GetParent_WithInvalidIndex_ThrowsOutOfRangeException(int index)
{
//Arrange
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);

//Act/Assert
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => treeListViewItemsCollection.GetParent(index));
Expand All @@ -610,7 +610,7 @@ public void GetParent_WithNestedItem_ReturnsParent()
{
//Arrange
ObservableCollection<string> boundCollection = new() { "0", "1", "2" };
TreeListViewItemsCollection<string> treeListViewItemsCollection = new(boundCollection);
TreeListViewItemsCollection treeListViewItemsCollection = new(boundCollection);
treeListViewItemsCollection.InsertWithLevel(2, "1_0", 1);
treeListViewItemsCollection.InsertWithLevel(3, "1_1", 1);
treeListViewItemsCollection.InsertWithLevel(4, "1_2", 1);
Expand Down Expand Up @@ -674,15 +674,15 @@ public void ReplaceAllItems(params T[] newItems)

public static class TreeListViewItemsCollectionExtensions
{
public static IEnumerable<int> GetAllLevels<T>(this TreeListViewItemsCollection<T> collection)
public static IEnumerable<int> GetAllLevels(this TreeListViewItemsCollection collection)
{
for (int i = 0; i < collection.Count; i++)
{
yield return collection.GetLevel(i);
}
}

public static IEnumerable<bool> GetAllIsExpanded<T>(this TreeListViewItemsCollection<T> collection)
public static IEnumerable<bool> GetAllIsExpanded(this TreeListViewItemsCollection collection)
{
for (int i = 0; i < collection.Count; i++)
{
Expand Down
Loading

0 comments on commit 9c8ff77

Please sign in to comment.