diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/Given_CollectionView.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/Given_CollectionView.cs new file mode 100644 index 000000000000..7ed33a9d99d9 --- /dev/null +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/Given_CollectionView.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.Metrics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml; +using Windows.Foundation.Collections; + +namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Data; + +[TestClass] +[RunsOnUIThread] +public class Given_CollectionView +{ + [TestMethod] + public void When_Grouped_With_ItemsPath() + { + var data = new List + { + new("1", "Test 1|1", "Group 1"), + new("2", "Test 2|1", "Group 1"), + new("3", "Test 3|1", "Group 1"), + new("4", "Test 1|2", "Group 2"), + new("5", "Test 2|2", "Group 2"), + new("6", "Test 3|2", "Group 2"), + new("7", "Test 1|3", "Group 3"), + new("8", "Test 2|3", "Group 3"), + new("9", "Test 3|3", "Group 3"), + }; + + var groupedItems = from item in data + group item by item.GroupName into g + select new { GroupName = g.Key, Items = g.ToList() }; + + var cvs = new CollectionViewSource(); + cvs.IsSourceGrouped = true; + cvs.ItemsPath = new PropertyPath("Items"); + cvs.Source = groupedItems.ToList(); + + var type = GetItemType(cvs.View); + Assert.AreEqual(typeof(GroupItemDto), type); + } + + [TestMethod] + public void When_Grouped_Get_Count() + { + var data = new List + { + new("1", "Test 1|1", "Group 1"), + new("2", "Test 2|1", "Group 1"), + new("3", "Test 3|1", "Group 1"), + new("4", "Test 1|2", "Group 2"), + new("5", "Test 2|2", "Group 2"), + new("6", "Test 3|2", "Group 2"), + new("7", "Test 1|3", "Group 3"), + new("8", "Test 2|3", "Group 3"), + new("9", "Test 3|3", "Group 3"), + }; + + var groupedItems = from item in data + group item by item.GroupName into g + select new { GroupName = g.Key, Items = g.ToList() }; + + var cvs = new CollectionViewSource(); + cvs.IsSourceGrouped = true; + cvs.ItemsPath = new PropertyPath("Items"); + cvs.Source = groupedItems.ToList(); + + var count = GetCount(cvs.View); + Assert.AreEqual(9, count); + } + + private int GetCount(ICollectionView view) + { + int num = 0; + IEnumerable dataSource = view; + if (dataSource != null) + { + IEnumerator enumerator = dataSource.GetEnumerator(); + if (enumerator != null) + { + while (enumerator.MoveNext()) + { + num++; + } + } + } + return num; + } + + private Type GetItemType(IEnumerable list) + { + Type type = list.GetType(); + Type type2 = null; + bool flag = false; + if (type2 == null || type2 == typeof(object) || flag) + { + Type type3 = null; + IEnumerator enumerator = list.GetEnumerator(); + type3 = ((!enumerator.MoveNext() || enumerator.Current == null) ? + (from object x in list select x.GetType()).FirstOrDefault() : enumerator.Current.GetType()); + if (type3 != typeof(object)) + { + return type3; + } + } + if (flag) + { + return null; + } + return type2; + } + + private record GroupItemDto(string Number, string Name, string GroupName); +} diff --git a/src/Uno.UI.Tests/Windows_UI_XAML_Controls/ItemsControlTests/Given_ItemsControl.cs b/src/Uno.UI.Tests/Windows_UI_XAML_Controls/ItemsControlTests/Given_ItemsControl.cs index 93f84817768d..4d8fe7d5243f 100644 --- a/src/Uno.UI.Tests/Windows_UI_XAML_Controls/ItemsControlTests/Given_ItemsControl.cs +++ b/src/Uno.UI.Tests/Windows_UI_XAML_Controls/ItemsControlTests/Given_ItemsControl.cs @@ -311,9 +311,7 @@ public void When_GroupedCollectionViewSource() SUT.ItemsSource = cvs; - // This behavior is not the UWP one, this assertion - // is present to freeze the behavior. - Assert.AreEqual(0, count); + Assert.AreEqual(11, count); } #endif diff --git a/src/Uno.UI/UI/Xaml/Data/CollectionView.cs b/src/Uno.UI/UI/Xaml/Data/CollectionView.cs index 44bda1834b41..88bdebbb703d 100644 --- a/src/Uno.UI/UI/Xaml/Data/CollectionView.cs +++ b/src/Uno.UI/UI/Xaml/Data/CollectionView.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; -using System.Text; using Uno; using Uno.Extensions; using Uno.Extensions.Specialized; @@ -172,16 +171,6 @@ public int Count public event VectorChangedEventHandler VectorChanged; //TODO: this should be raised if underlying source implements INotifyCollectionChanged #pragma warning restore 67 // Unused member - public IEnumerator GetEnumerator() - { - // In Windows if CollectionView is from a CollectionViewSource marked grouped, it enumerates the flattened list of objects - if (_isGrouped) - { - return (_collection as IEnumerable> ?? Enumerable.Empty>()).SelectMany(g => g).GetEnumerator(); - } - return (_collection as IEnumerable)?.GetEnumerator(); - } - public IAsyncOperation LoadMoreItemsAsync(uint count) { throw new NotSupportedException(); @@ -274,11 +263,21 @@ IEnumerator IEnumerable.GetEnumerator() // In Windows if CollectionView is from a CollectionViewSource marked grouped, it enumerates the flattened list of objects if (_isGrouped) { - return (_collection as IEnumerable ?? Enumerable.Empty()).SelectManyUntyped(g => g).GetEnumerator(); + return CollectionGroups.OfType().SelectManyUntyped(c => c.GroupItems).GetEnumerator(); } return (_collection as IEnumerable).GetEnumerator(); } + public IEnumerator GetEnumerator() + { + // In Windows if CollectionView is from a CollectionViewSource marked grouped, it enumerates the flattened list of objects + if (_isGrouped) + { + return CollectionGroups.OfType().SelectMany(c => c.GroupItems).GetEnumerator(); + } + return (_collection as IEnumerable)?.GetEnumerator(); + } + public int IndexOf(object item) => _collection.IndexOf(item); void IList.Insert(int index, object item) => (_collection as IList ?? throw new NotSupportedException()).Insert(index, item); diff --git a/src/Uno.UI/UI/Xaml/Data/CollectionViewSource.cs b/src/Uno.UI/UI/Xaml/Data/CollectionViewSource.cs index d181113a2fe3..acf534207026 100644 --- a/src/Uno.UI/UI/Xaml/Data/CollectionViewSource.cs +++ b/src/Uno.UI/UI/Xaml/Data/CollectionViewSource.cs @@ -62,7 +62,7 @@ public ICollectionView View private set => SetValue(ViewProperty, value); } - public global::Microsoft.UI.Xaml.PropertyPath ItemsPath + public PropertyPath ItemsPath { get => (PropertyPath)this.GetValue(ItemsPathProperty); set => this.SetValue(ItemsPathProperty, value);