Implement data grouping feature for WinUI TableView#340
Implement data grouping feature for WinUI TableView#340JanviMahajan14 wants to merge 5 commits intow-ahmad:mainfrom
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…uping_rows # Conflicts: # src/TableView.cs
michael-hawker
left a comment
There was a problem hiding this comment.
Now that #337 is merged, we should also ensure to add a sample to showcase this improvement (and help test it).
| private readonly ObservableCollection<object> _displayItems = []; | ||
|
|
||
| // Maps GroupHeaderRowItem sentinels to their display text (e.g., "Engineering (4)"). | ||
| private readonly Dictionary<object, string> _groupHeadersByItem = new(ReferenceEqualityComparer.Instance); |
There was a problem hiding this comment.
Would anything like the ObservableGroup APIs help with this logic? Going to pull this down to try first-hand a bit more to understand the setup here.
There was a problem hiding this comment.
Thanks for the suggestion! I explored the ObservableGroup<TKey, TElement> APIs from the CommunityToolkit. The challenge with our current approach is that ListView needs a single flat list to render — so _displayItems contains data items interleaved with group header sentinels (e.g., [Header: "Engineering (3)"], [Alice], [Bob], [Charlie],[Header: "Sales (2)"], ...). The ObservableGroupedCollection gives us a hierarchical IGrouping<TKey, T> structure, which doesn't directly map to this flat interleaved list.
The dictionaries here are O(1) lookup caches used during rendering and expand/collapse to quickly answer: "what group does this item belong to?" and "what's the header for this group?"
That said, as we move the grouping logic into CollectionView (planned for next iteration), we could potentially use ObservableGroup as the internal group model and flatten it into the display list as a separate step. Happy to discuss further once you've had a chance to pull it down!
w-ahmad
left a comment
There was a problem hiding this comment.
Thanks for the PR @JanviMahajan14!
It seems the entire new implementation was added for the grouping purposes. Why not just use CollectionViewSource? I think it would simplify the process and also allow TableView to work within SemanticZoom.
Thanks for the review @w-ahmad! . The reason I went with the custom approach was because TableView already wraps ItemsSource in its own internal CollectionView for sorting and filtering, and I wasn't sure how CollectionViewSource + IsSourceGrouped would interact with that existing pipeline. There were also concerns about group headers needing to span across the frozen/scrollable column layout. That said, I think it's worth exploring the CollectionViewSource approach — it would be cleaner and more aligned with the WinUI platform. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
While exploring the implementation of groups using CollectionView.CollectionGroups, I found it to be very simple and useful, and it also works with SemanticZoom. void GetCollectionGroups()
{
foreach (var group in _view.GroupBy(GroupKeySelector))
{
var cvw = new CollectionViewGroup(group.Key, group);
CollectionGroups?.Add(cvw);
}
}Screen.Recording.2026-04-14.182836.mp4The expand and collapse feature can be implemented with just a few lines of code. To expand, add all the grouped items to the CollectionGroup.GroupItems, and to collapse, simply clear the GroupItems. void ToggleGroup(GroupInfo group)
{
group.IsExpanded = !group.IsExpanded;
if (group.IsExpanded)
{
group.CollectionViewGroup.GroupItems = new ObservableVector<object?>(group.Items);
}
else
{
group.CollectionViewGroup.GroupItems.Clear();
}
OnVectorChanged(new VectorChangedEventArgs(CollectionChange.Reset, 0));
}The only issue is that when collapsing (clearing the group items), the ItemsStackPanel doesn’t properly clear item containers and keeps them in the visual tree. I’m looking for a workaround for this and will also open an issue in the WinUI repo. Screen.Recording.2026-04-14.184305.mp4 |
|
@w-ahmad , thanks for sharing this. CollectionView.CollectionGroups looks like a promising approach. I’ll try implementing it as well and see how it performs across different scenarios. |
ac18493 to
a1649dc
Compare
This pull request adds grouping functionality to the
TableViewcomponent, enabling users to group items by a specified property, display group headers (with optional item counts), and expand or collapse groups. The changes also ensure that group headers are not selectable or editable, and that UI updates are efficiently managed.Address #69
Sharing a Preview video from my Sample Test App:
Grouping_feature.mp4
Sharing a Preview video after adding a Grouping Page in WinUI Samples
grouping_sample_app_demo.mp4