Repository navigation
Introducing TableView: a native data table for WinUI 3 馃搳 #12400
Pranav Gupta (pranav-gupta-msft)
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Hello WinUI community!
TableView is experimental and still a work in progress. We're sharing it early so the community can try it, find rough edges, and help shape it through feedback and bug reports. APIs and behavior may change. If something doesn't work as expected, please file an issue.
For a long time, the community has asked for data table support in WinUI 3. As a first step in that direction, we're sharing the TableView control as an experimental release.
Windows App SDK 2.5.4-experimental includes TableView, a first-party, Fluent-styled table control in the
Microsoft.UI.Xaml.Controls.Tabularnamespace. It brings column templates, sorting, filtering, grouping and cell editing together in a native WinUI 3 control.Work is already in progress to support hierarchical views and app context menus in upcoming iterative updates.
What we built with it
To explore TableView in a realistic scenario, we built Contoso Sales Ledger, a pipeline ledger for a regional sales team. It brings together 5,000 deals and eleven columns, with a strip of KPI cards above the table built from standard WinUI controls.
The full-ledger screenshots include app-defined toolbar controls; these are not built-in TableView UI.
Columns are declared in XAML. Use a
TableViewTextColumnfor plain values, or aTableViewTemplateColumnwhen a cell needs real UI. In the ledger, templates render an initials avatar next to the account name, a colored pill for the deal stage and a progress bar for win probability. Rows are virtualized, so the control does not need to create a visual row for every deal at once.Start with a C# WinUI 3 project named
SalesLedger, using the package and resource dictionaries in Project setup below. The excerpts are point-in-time versions: each section includes only the code needed for the feature being introduced. Existing Window tags, C# imports and namespace declarations are omitted.In
MainWindow.xaml, replace the content inside your existingWindowwith the XAML below. InMainWindow.xaml.cs, keep the imports and namespace, replace the existingMainWindowclass, and addDealalongside it in the same namespace. The code-behind only creates the data and assigns it to the table; it has no sorting, filtering or grouping logic.MainWindow.xaml - content inside Window
MainWindow.xaml.cs - data only
Run the app now: it displays twelve deals in their original list order.
ItemsSourcesupplies the rows; the XAML bindings only describe how to display each one. The model contains just the properties used by these columns, includingOwnerfor the Deal tooltip.Click a column header to sort by that column. TableView's built-in header UI sorts one column at a time; choosing another column replaces the current sort.
No additional code-behind is needed for header-click sorting in the example above.
CanUserSortColumnsis enabled; text columns use their bindings, and template columns useSortMemberPath. Amount sorts by the numericAmountproperty rather than the formattedAmountText.The GIF shows the full ledger demo, including its app-defined sorting controls.
馃攷 Filter and group
TableViewSourcecombines filtering, sorting and grouping. Text matching is implemented by the app's filter predicate, not by a separate TableView search feature. The full ledger combines a text box with a Region picker and updates its KPI cards for matching deals.For this next step, replace the content inside
Windowand theMainWindow/Dealclass definitions with the matching excerpts below. Keep the existing Window header and C# imports/namespace. Only now do we add a text box, a Clear button and their handlers. TheRegionproperty and its sample values are also introduced here, because grouping now needs them. The Amount sort from the preceding step is retained.MainWindow.xaml - add the filtering controls
MainWindow.xaml.cs - add filtering and grouping
Entering
Cloudfilters the view to three deals across two regions. Clear restores all twelve deals, still grouped by region. Each text change reapplies the filter and grouping, with descending Amount order within each group. NoMatcheshelper or Region picker is needed for this example.Grouping takes a key selector, and the runnable example uses TableView's built-in group headers. The full ledger adds a
GroupHeaderTemplateto present each region with its deal count and open pipeline. TableView supplies the group key and item count; the app calculates the pipeline total. Groups collapse and expand, and the sort order applies within each group.鉁忥笍 Editing with validation
The runnable examples above remain read-only. The editing workflow shown here belongs to the full ledger application.
Set
IsReadOnly="False"and give a template column aCellEditingTemplateto make its cells editable. Start an edit with a double-click or F2, commit with Enter, or cancel with Esc.CellEditEndinglets your app veto a commit. Check thatEditActionisCommit, validate the proposed value and setargs.Cancel = trueto keep the editor open when the value is invalid. Validate the pending editor value rather than assuming it has already reached the data item.In the ledger, entering a negative amount turns the editor's border red, shows an error icon and opens an
InfoBarexplaining the rule. The validation rule and feedback UI belong to the app; TableView provides the editing lifecycle.Frozen columns, density and tooltips
Wide tables are easier to read when the identifying column stays put. With
FrozenEdge="Leading", the Deal column stays pinned while you scroll across the rest of the ledger.Densityswitches between Compact, Standard and Comfortable with one property. Choose tighter rows for a data-heavy screen or more spacious rows for touch interaction.HeaderToolTipandCellToolTipBindingadd context without cluttering the table, from an explanation of a column's sort order to extra details about a deal.Try it out
Install Microsoft.WindowsAppSDK 2.5.4-experimental, read the release notes and explore the experimental Tabular API reference.
For this release, use
WindowsAppSDKSelfContained=truealong with the resource merge to avoid the framework-dependent startup issue reported in #12115. The setup below includes both.Project setup
Create a C# WinUI 3 app named
SalesLedgerwith Microsoft.WindowsAppSDK 2.5.4-experimental. Keep the template'sApp.xaml.cs.PropertyGroup, setWindowsAppSDKSelfContained=true,WindowsPackageType=NoneandEnableMsixTooling=false.Properties\launchSettings.json, use an unpackaged profile withcommandNameset toProject, and select it in Visual Studio.XamlControlsResourcesandTabularControlsResourcesin application resources; addxmlns:tv="using:Microsoft.UI.Xaml.Controls.Tabular"to the existingWindow.System,System.Collections.Generic,System.Globalization,Microsoft.UI.Xaml,Microsoft.UI.Xaml.Controls,Microsoft.UI.Xaml.Controls.TabularandMicrosoft.UI.Xaml.Data.馃挰 Tell us what you think
TableView is still experimental. There are rough edges, and the examples above aren't a claim that every scenario is ready. Your feedback helps us understand where the control needs more work.
We're grateful to everyone who has already tried TableView and filed reports. From early feedback, we've identified enhancements, and these will be fixed as part of upcoming releases. Please keep the feedback coming.
Here are some of the bugs the community has reported:
The community has also proposed additional functionality:
Check existing TableView issues first: if you encounter the same problem, add your reproduction details there; for a different problem, file a new issue. Include the Windows App SDK version, steps to reproduce, what you expected and what happened, and a minimal repro or relevant screenshot where possible. You can also share broader feedback in WinUI discussions.
Pranav Gupta
Team WinUI 馃挋
All reactions