Guide for implementing Syncfusion WinUI DataGrid (SfDataGrid) for tabular data display in desktop applications. Use this skill when working with data grids, sorting, filtering, grouping, or CRUD operations. Covers data binding, column configuration, master-details views, Excel export, and performance optimization including data virtualization and custom templates.
Comprehensive guide for implementing the Syncfusion WinUI DataGrid control. SfDataGrid is a high-performance, feature-rich control for displaying and manipulating tabular data in WinUI 3 applications with support for sorting, filtering, grouping, editing, summaries, and more.
Use this skill when you need to:
Important Note: In WinUI 3, DataContext is not directly inherited from Window. You must explicitly set DataContext on the Grid or Page element in XAML (e.g., ) for data binding to work properly.
<Grid DataContext="{x:Bind ViewModel}">SfDataGrid (Syncfusion.UI.Xaml.DataGrid.SfDataGrid) is the primary grid control for WinUI 3, offering:
Required Packages:
Syncfusion.Grid.WinUI (DataGrid control)Syncfusion.GridExport.WinUI (Excel export functionality)Syncfusion.XlsIO.NET (Required for export operations)Namespace: Syncfusion.UI.Xaml.DataGrid
📄 Read: references/getting-started.md
📄 Read: references/columns.md
📄 Read: references/data-operations.md
📄 Read: references/editing-validation.md
📄 Read: references/selection.md
📄 Read: references/summaries.md
📄 Read: references/row-features.md
📄 Read: references/virtualization.md
📄 Read: references/export.md
<!-- MainPage.xaml -->
<Page xmlns:dataGrid="using:Syncfusion.UI.Xaml.DataGrid">
<Grid>
<dataGrid:SfDataGrid x:Name="sfDataGrid"
ItemsSource="{Binding Orders}"
AutoGenerateColumns="True"
AllowSorting="True"
AllowFiltering="True"
AllowEditing="True"
SelectionMode="Single" />
</Grid>
</Page>
// MainPage.xaml.cs
using Microsoft.UI.Xaml.Controls;
using System.Collections.ObjectModel;
public sealed partial class MainPage : Page
{
public ObservableCollection<Order> Orders { get; set; }
public MainPage()
{
this.InitializeComponent();
Orders = new ObservableCollection<Order>
{
new Order { OrderID = 1001, CustomerName = "Maria Anders", Country = "Germany", Total = 250.50M },
new Order { OrderID = 1002, CustomerName = "Ana Trujillo", Country = "Mexico", Total = 180.00M },
new Order { OrderID = 1003, CustomerName = "Antonio Moreno", Country = "Mexico", Total = 420.75M }
};
sfDataGrid.ItemsSource = Orders;
}
}
// Order Model
public class Order
{
public int OrderID { get; set; }
public string CustomerName { get; set; }
public string Country { get; set; }
public decimal Total { get; set; }
}
<dataGrid:SfDataGrid x:Name="sfDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding Orders}">
<dataGrid:SfDataGrid.Columns>
<dataGrid:GridTextColumn MappingName="OrderID"
HeaderText="Order ID"
Width="120" />
<dataGrid:GridTextColumn MappingName="CustomerName"
HeaderText="Customer"
Width="200" />
<dataGrid:GridTextColumn MappingName="Country"
Width="150" />
<dataGrid:GridNumericColumn MappingName="Total"
HeaderText="Total Amount"
Width="150" />
</dataGrid:SfDataGrid.Columns>
</dataGrid:SfDataGrid>
<dataGrid:SfDataGrid x:Name="sfDataGrid"
ItemsSource="{Binding Orders}"
AllowSorting="True"
AllowFiltering="True"
FilterRowPosition="FixedTop"
AllowTriStateSorting="True" />
<dataGrid:SfDataGrid x:Name="sfDataGrid"
ItemsSource="{Binding Orders}"
AllowGrouping="True"
ShowGroupDropArea="True" />
// Programmatic grouping
sfDataGrid.GroupColumnDescriptions.Add(new GroupColumnDescription { ColumnName = "Country" });
<dataGrid:SfDataGrid x:Name="sfDataGrid"
ItemsSource="{Binding Orders}"
AllowEditing="True"
EditTrigger="OnDoubleTap"
NavigationMode="Cell" />
<dataGrid:SfDataGrid x:Name="sfDataGrid"
ItemsSource="{Binding Orders}"
ShowRowHeader="True">
<dataGrid:SfDataGrid.TableSummaryRows>
<dataGrid:GridTableSummaryRow ShowSummaryInRow="False">
<dataGrid:GridTableSummaryRow.SummaryColumns>
<dataGrid:GridSummaryColumn Name="TotalSum"
MappingName="Total"
SummaryType="DoubleAggregate"
Format="'Total: {Sum:C}'" />
<dataGrid:GridSummaryColumn Name="OrderCount"
MappingName="OrderID"
SummaryType="CountAggregate"
Format="'Count: {Count}'" />
</dataGrid:GridTableSummaryRow.SummaryColumns>
</dataGrid:GridTableSummaryRow>
</dataGrid:SfDataGrid.TableSummaryRows>
</dataGrid:SfDataGrid>
| Property | Type | Description |
|---|---|---|
ItemsSource | object | Data source for the grid (IEnumerable) |
AutoGenerateColumns | bool | Auto-create columns from data source properties |
Columns | Columns | Collection of manually defined columns |
AllowSorting | bool | Enable/disable sorting (default: false) |
AllowFiltering | bool | Enable/disable filtering (default: false) |
AllowGrouping | bool | Enable/disable grouping (default: false) |
AllowEditing | bool | Enable/disable editing (default: false) |
SelectionMode | GridSelectionMode | Single, Multiple, Extended, None |
SelectionUnit | GridSelectionUnit | Row or Cell |
NavigationMode | NavigationMode | Cell or Row navigation |
ColumnWidthMode | ColumnWidthMode | None, Star, Auto, SizeToCells, SizeToHeader, AutoLastColumnFill, AutoWithLastColumnFill |
ShowGroupDropArea | bool | Show drag-and-drop area for grouping |
FilterRowPosition | FilterRowPosition | FixedTop, Top, Bottom |
// ViewModel
public class OrderViewModel : INotifyPropertyChanged
{
private ObservableCollection<Order> orders;
private Order selectedOrder;
public ObservableCollection<Order> Orders
{
get => orders;
set { orders = value; OnPropertyChanged(); }
}
public Order SelectedOrder
{
get => selectedOrder;
set { selectedOrder = value; OnPropertyChanged(); }
}
public ICommand DeleteCommand { get; }
public ICommand ExportCommand { get; }
}
<!-- View -->
<dataGrid:SfDataGrid ItemsSource="{Binding Orders}"
SelectedItem="{Binding SelectedOrder, Mode=TwoWay}" />
Data not displaying:
ItemsSource is bound correctlyDataContext is set if using bindingEditing not working:
AllowEditing="True"NavigationMode="Cell"AllowEditing="True" (inherited from grid if not set)Poor performance with large datasets:
ColumnWidthMode="None" instead of AutoSorting/Filtering not working:
AllowSorting="True" and/or AllowFiltering="True"