Skip to content

Implement data grouping feature for WinUI TableView#340

Open
JanviMahajan14 wants to merge 5 commits intow-ahmad:mainfrom
JanviMahajan14:user/janvimahajan/grouping_rows
Open

Implement data grouping feature for WinUI TableView#340
JanviMahajan14 wants to merge 5 commits intow-ahmad:mainfrom
JanviMahajan14:user/janvimahajan/grouping_rows

Conversation

@JanviMahajan14
Copy link
Copy Markdown

@JanviMahajan14 JanviMahajan14 commented Apr 7, 2026

This pull request adds grouping functionality to the TableView component, 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

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JanviMahajan14 JanviMahajan14 marked this pull request as draft April 7, 2026 03:48
Comment thread src/TableView.Properties.cs
@JanviMahajan14 JanviMahajan14 marked this pull request as ready for review April 9, 2026 15:48
…uping_rows

# Conflicts:
#	src/TableView.cs
Copy link
Copy Markdown

@michael-hawker michael-hawker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that #337 is merged, we should also ensure to add a sample to showcase this improvement (and help test it).

Comment thread src/TableView.Properties.cs Outdated
Comment thread src/TableView.Grouping.cs
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);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Author

@JanviMahajan14 JanviMahajan14 Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

Copy link
Copy Markdown
Owner

@w-ahmad w-ahmad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@JanviMahajan14
Copy link
Copy Markdown
Author

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.

Janvi Mahajan and others added 2 commits April 13, 2026 12:59
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@w-ahmad
Copy link
Copy Markdown
Owner

w-ahmad commented Apr 14, 2026

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.mp4

The 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

@JanviMahajan14
Copy link
Copy Markdown
Author

@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.

@JanviMahajan14 JanviMahajan14 force-pushed the user/janvimahajan/grouping_rows branch 2 times, most recently from ac18493 to a1649dc Compare April 15, 2026 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants