Grouping in WinUI DataGrid

18 Apr 202224 minutes to read

DataGrid allows you to group the data against one or more columns. When grouping is applied, the data is organized into a hierarchical structure based on matching column values and it is sorted by ascending order.

SfDataGrid allows you to group the data in below ways,

  • UI Grouping
  • Programmatic Grouping

UI grouping

You can allow end-user to group the data by setting SfDataGrid.AllowGrouping property to true , where user can drag and drop the column into GroupDropArea to group based on that column.

When the column is grouped, records that have an identical value in the column are combined to form a group. The GroupDropArea can be enabled by setting the SfDataGrid.ShowGroupDropArea property to true.

<dataGrid:SfDataGrid  x:Name="sfDataGrid"
                        AllowGrouping="True"
                        AutoGenerateColumns="True"
                        ItemsSource="{Binding Orders}"
                        ShowGroupDropArea="True" />
this.sfDataGrid.AllowGrouping = true;

You can enable or disable grouping on particular column by setting the GridColumn.AllowGrouping property.

<dataGrid:SfDataGrid  x:Name="sfDataGrid"
                        AutoGenerateColumns="False"
                        AllowGrouping="True"						
                        ItemsSource="{Binding Orders}"
                        ShowGroupDropArea="True">
    <dataGrid:SfDataGrid.Columns>
        <dataGrid:GridTextColumn AllowGrouping="True" MappingName="OrderID" />
        <dataGrid:GridTextColumn AllowGrouping="False" MappingName="CustomerID" />        
    </dataGrid:SfDataGrid.Columns>
</dataGrid:SfDataGrid>
this.sfDataGrid.Columns["OrderID"].AllowGrouping = true;
this.sfDataGrid.Columns["CustomerID"].AllowGrouping = false;

NOTE

GridColumn.AllowGrouping takes higher priority than SfDataGrid.AllowGrouping.

WinUI DataGrid Grouping

The data can be grouped by an unlimited number of columns. To group more than one columns, drag-and-drop the desired columns in to GroupDropArea.

Multiple Grouping in WinUI DataGrid

Each group is identified by its CaptionSummaryRow and it is used to organize the data into a hierarchical tree structure based on identical values of that column. The underlying records in each caption summary row can be expanded or collapsed by clicking its group caption.

Each CaptionSummaryRow carries information about a particular group like group name, number of items (records) in the group, etc. You can refer Caption Summaries section, for more information about CaptionSummaryRow.

Programmatic grouping

SfDataGrid allows you to group the data programmatically by adding or removing GroupColumnDescription to SfDataGrid.GroupColumnDescriptions collection.

For example, if you want to group the OrderID column programmatically, define its MappingName to ColumnName property of GroupColumnDescription. Then add the GroupColumnDescription to the SfDataGrid.GroupColumnDescriptions collection.

<dataGrid:SfDataGrid  x:Name="sfDataGrid"
                        AllowGrouping="True"
                        AutoGenerateColumns="True"
                        ItemsSource="{Binding Orders}"
                        ShowGroupDropArea="True">
    <dataGrid:SfDataGrid.GroupColumnDescriptions>
        <dataGrid:GroupColumnDescription ColumnName="OrderID" />
    </dataGrid:SfDataGrid.GroupColumnDescriptions>
</dataGrid:SfDataGrid>
this.sfDataGrid.GroupColumnDescriptions.Add(new GroupColumnDescription() { ColumnName = "OrderID" });

You can group more than one column programmatically.

<dataGrid:SfDataGrid x:Name="sfDataGrid"
                        AllowGrouping="True"                               
                        ItemsSource="{Binding Orders}"
                        ShowGroupDropArea="True">

    <dataGrid:SfDataGrid.GroupColumnDescriptions>
        <dataGrid:GroupColumnDescription ColumnName="OrderID" />
        <dataGrid:GroupColumnDescription ColumnName="CustomerID" />
    </dataGrid:SfDataGrid.GroupColumnDescriptions>

</dataGrid:SfDataGrid>
this.sfDataGrid.View.BeginInit();
this.sfDataGrid.GroupColumnDescriptions.Add(new GroupColumnDescription() { ColumnName = "OrderID" });
this.sfDataGrid.GroupColumnDescriptions.Add(new GroupColumnDescription() { ColumnName = "CustomerID" });
this.sfDataGrid.View.EndInit();

Group based on display text

You can group the column in DataGrid based on the value being displayed in cell by setting GridColumn.GroupMode as Display.
In the below example, OrderID column displays value with one decimal digit in cell. But when you group, groups will be created based on actual value considering all decimal digits of value (Refer right side screen shot). You can group based value displayed in the cell by setting GridColumn.GroupMode as Display (Refer left side screen shot for the same data).

xmlns:core="using:Syncfusion.UI.Xaml.Core"

<Page.Resources>
    <core:StringFormatConverter x:Key="stringFormatConverter" />
</Page.Resources>
<dataGrid:GridTextColumn HeaderText="Order ID"  
                           TextAlignment="Right"
                           DisplayBinding="{Binding OrderID, 
                           Converter={StaticResource stringFormatConverter}, ConverterParameter=\{0:N1\}}" 
                           GroupMode="Display"/>
this.sfDataGrid.Columns["OrderID"].GroupMode = DataReflectionMode.Display;

Grouped Column in WinUI DataGrid based on Display Text

Group caption based on DisplayMember when grouping GridComboBoxColumn

In SfDataGrid, you can group the column based on display value and also the same can be displayed in caption summary by setting GridColumn.GroupMode as Display.

<dataGrid:GridComboBoxColumn MappingName="ShipCityID" HeaderText="Ship Country" SelectedValuePath="ShipCityID" DisplayMemberPath="ShipCityName" ItemsSource="{Binding ComboItemSource, Source={StaticResource viewModel}}" GroupMode="Display" />
this.sfDataGrid.Columns.Add(new GridComboBoxColumn()
{
    ItemsSource = viewModel.ComboItemSource,
    DisplayMemberPath = "ShipCityName",
    HeaderText= "Ship Country",
    MappingName = "ShipCityID",
    SelectedValuePath = "ShipCityID",
    GroupMode = DataReflectionMode.Display
});

Grouped Column in WinUI DataGrid based on Display Member

Clearing or removing group

You can remove all the groups by clearing SfDataGrid.GroupColumnDescriptions collection.

this.sfDataGrid.GroupColumnDescriptions.Clear();

You can ungroup the column programmatically at runtime by removing GroupColumnDescription from SfDataGrid.GroupColumnDescriptions collection.

this.sfDataGrid.View.BeginInit();            
this.sfDataGrid.GroupColumnDescriptions.Remove(this.sfDataGrid.GroupColumnDescriptions[0]);
this.sfDataGrid.View.EndInit();

To ungroup the column in UI, click the close button on column header or drag the column header from the GroupDropArea and drop it on the header row.

WinUI DataGrid Column without Grouping

Hiding the column when grouped

You can hide the column header when the particular column gets grouped by setting SfDataGrid.ShowColumnWhenGrouped property to false.

<dataGrid:SfDataGrid  x:Name="sfDataGrid"
                        AutoGenerateColumns="True"
                        AllowGrouping="True"						
                        ItemsSource="{Binding Orders}"
                        ShowColumnWhenGrouped="False"
                        ShowGroupDropArea="True" />
this.sfDataGrid.ShowColumnWhenGrouped = false;

Hide Grouping Column in WinUI DataGrid

Freezing caption rows when scrolling

You can freeze the group caption of the group in view until its records scrolled out of the view by setting the SfDataGrid.AllowFrozenGroupHeaders property to true.

<dataGrid:SfDataGrid  x:Name="sfDataGrid"                            
                        AutoGenerateColumns="True"
                        AllowGrouping="True"						
                        AllowFrozenGroupHeaders="True"
                        ItemsSource="{Binding Orders}"
                        ShowGroupDropArea="True" />
this.sfDataGrid.AllowFrozenGroupHeaders = true;

WinUI DataGrid with Frozen Caption Summary Rows

Expanding or collapsing the groups

By default, you can view the records in each group by expanding or collapsing its group caption.

You can allow end-user to expand or collapse the groups programmatically at runtime.

Expand groups while grouping

You can expand all the groups while grouping by setting SfDataGrid.AutoExpandGroups to true. So, when user group any column, then all groups will be in expanded state.

<dataGrid:SfDataGrid  x:Name="sfDataGrid"
                        AutoExpandGroups="True"
                        AllowGrouping="True"						
                        AutoGenerateColumns="True"
                        ItemsSource="{Binding Orders}"
                        ShowGroupDropArea="True" />
this.sfDataGrid.AutoExpandGroups = true;

Programmatically expand or collapse the groups

Expand or collapse all the Groups

You can expand or collapse all the groups at programmatically at runtime by using SfDataGrid.ExpandAllGroup and SfDataGrid.CollapseAllGroup methods.

this.sfDataGrid.ExpandAllGroup();
this.sfDataGrid.CollapseAllGroup();

Expand or Collapse the Group based on its level

You can expand or collapse the group based on its level by using SfDataGrid.ExpandGroupsAtLevel and SfDataGrid.CollapseGroupsAtLevel methods.

this.sfDataGrid.ExpandGroupsAtLevel(2);
this.sfDataGrid.CollapseGroupsAtLevel(2);

Expand or Collapse the specific Group

You can expand or collapse specific group by using SfDataGrid.ExpandGroup and SfDataGrid.CollapseGroup methods.

var group = sfDataGrid.View.CollectionGroups[0] as Group;
this.sfDataGrid.ExpandGroup(group);
this.sfDataGrid.CollapseGroup(group);

Customize indent column width

You can customize the width of IndentColumn in SfDataGrid by using IndentColumnWidth property as like below.

<dataGrid:SfDataGrid x:Name="sfDataGrid"                                      
                       AllowGrouping="True"
                       IndentColumnWidth="50"
                       ShowGroupDropArea="True"
                       ItemsSource="{Binding OrderInfoCollection }">
this.sfDataGrid.IndentColumnWidth = 50;

GroupDropArea customization

GroupDropArea text

You can change the GroupDropArea’s text by setting SfDataGrid.GroupDropAreaText property.

<dataGrid:SfDataGrid x:Name="sfDataGrid"
                       AllowGrouping="True"
                       GroupDropAreaText="Drag and drop the columns here"
                       ItemsSource="{Binding Orders}"
                       ShowGroupDropArea="True" />

WinUI DataGrid with Custom Group Drop Area Text

Expanding GroupDropArea while loading

By default, the GroupDropArea will be expanded while dragging the column towards the GroupDropArea. You can set the GroupDropArea to be always expanded by setting the SfDataGrid.IsGroupDropAreaExpanded property to true.

<dataGrid:SfDataGrid  x:Name="sfDataGrid"
                        AllowGrouping="True"
                        AutoGenerateColumns="True"
                        IsGroupDropAreaExpanded="True"
                        ItemsSource="{Binding Orders}"
                        ShowGroupDropArea="True" />
this.sfDataGrid.IsGroupDropAreaExpanded = true;

WinUI DataGrid with Expanded Group Drop Area

Custom grouping

DataGrid allows you to group the data based on custom logic when the built-in grouping functionality doesn’t meet your requirement.

To perform custom grouping on a particular column , specify the custom logic through GroupColumnDescription.KeySelector property and the column name to GroupColumnDescription.ColumnName property.

For an example, the Date column is grouped based on the week basis in the following example.

keySelector = (string ColumnName, object o) =>
{ 
    var dt = DateTime.Now;
    var item = (o as Employee).HireDate;
    var days = (int)Math.Floor((dt - item).TotalDays);
    var dayOfWeek = (int)dt.DayOfWeek;
    var difference = days - dayOfWeek;
    if (days <= dayOfWeek)
    {
        if (days == 0)
            return "TODAY";
        if (days == 1)
            return "YESTERDAY";
        return item.Date.DayOfWeek.ToString().ToUpper();
    }
    if (difference > 0 && difference <= 7)
        return "LAST WEEK";
    if (difference > 7 && difference <= 14)
        return "TWO WEEKS AGO";
    if (difference > 14 && difference <= 21)
        return "THREE WEEKS AGO";
    if (dt.Year == item.Date.Year && dt.Month == item.Date.Month)
        return "EARLIER THIS MONTH";
    if (DateTime.Now.AddMonths(-1).Month == item.Date.Month)
        return "LAST MONTH";
    return "OLDER";
};

private Func<string, object, object> keySelector;

public Func<string, object, object> KeySelector
{
    get
    {
        return keySelector;
    }
    set
    {
        keySelector = value;
    }
}

Now , assign the keySelector into GroupColumnDescription.KeySelector and set HireDate property to GroupColumnDescription.ColumnName property.

<Page.Resources>
    <local:EmployeeViewModel x:Key="viewModel"/>
</Page.Resources>
  
<dataGrid:SfDataGrid  x:Name="sfDataGrid"                          
                        AutoGenerateColumns="True"                          
                        ItemsSource="{Binding Employees}">

    <dataGrid:SfDataGrid.GroupColumnDescriptions>
        <dataGrid:GroupColumnDescription ColumnName="HireDate" KeySelector="{Binding KeySelector, Source={StaticResource viewModel}}" />
    </dataGrid:SfDataGrid.GroupColumnDescriptions>
        
</dataGrid:SfDataGrid>

WinUI DataGrid with Custom Grouping

You can refer here to apply custom sorting when grouping is applied.

Sorting the grouped column records

In custom grouping, you can sort all the inner records of each group by setting GroupColumnDescription.SortGroupRecords
sorted based on the column name described in GroupColumnDescription.

<dataGrid:SfDataGrid.GroupColumnDescriptions>
    <dataGrid:GroupColumnDescription ColumnName="SickLeaveHours"
                                       KeySelector="{Binding KeySelector, Source={StaticResource viewModel}}"
                                       SortGroupRecords="True" />
</dataGrid:SfDataGrid.GroupColumnDescriptions>
GroupColumnDescription groupColumnDescription = new GroupColumnDescription()
{
    ColumnName = "SickLeaveHours",
	SortGroupRecords = true,
    KeySelector = (string ColumnName, object o) =>
    {
        var item = (o as Employee).SickLeaveHours;
        if (item >= 1 && item <= 5)
            return "SickLeaveHours between 1-5";
        if (item >= 10 && item <= 15)
            return "SickLeaveHours between 10-15";
        if (item >= 5 && item <= 10)
            return "SickLeaveHours between 5-10";
        return "SickLeaveHours above 15";
    }    
};
sfDataGrid.GroupColumnDescriptions.Add(groupColumnDescription);

In the below screenshot custom grouping is applied based on SickLeaveHours column and the inner records in each group are sorted based on SickLeaveHours value.

Sorting Records under Group in WinUI DataGrid

Grouping events

GroupExpanding event

The SfDataGrid.GroupExpanding event occurs when the group is being expanded. The GroupChangingEventArgs of the GroupExpanding event provides the information about the expanding group and it has the following members.

  • Group - Gets the group that’s being expanded.

  • Cancel – Decides whether to cancel the group expansion.

You can cancel the group expansion by setting GroupChangingEventArgs.Cancel to true.

this.sfDataGrid.GroupExpanding += sfDataGrid_GroupExpanding;

void sfDataGrid_GroupExpanding(object sender, GroupChangingEventArgs e)
{
    if (e.Group.Key.Equals(1001))    
        e.Cancel = true;    
}

GroupExpanded event

The SfDataGrid.GroupExpanded event occurs after the group is expanded. The GroupChangedEventArgs of the GroupExpanded event provides the information about the expanded group and it has the following member.

  • Group - Gets the expanded group.

GroupCollapsing event

The SfDataGrid.GroupCollapsing event occurs when the group is being collapsed.

The GroupChangingEventArgs of the GroupCollapsing event provides the information about the collapsing group and it contains the following member.

  • Group - Gets the group that’s being collapsed.

  • Cancel – Decides whether to cancel the group collapsing.

You can cancel the group is being collapsed by using GroupChangingEventArgs.Cancel of GroupCollapsing event.

this.sfDataGrid.GroupCollapsing += SfDataGrid_GroupCollapsing;

void SfDataGrid_GroupCollapsing(object sender, GroupChangingEventArgs e)
{
    if (e.Group.Key.Equals(1001))    
        e.Cancel = true;    
}

GroupCollapsed event

The SfDataGrid.GroupCollapsed event occurs after the group is collapsed. GroupChangedEventArgs of the GroupCollapsed event provides the information about collapsed group and it contains the following member.

  • Group - Gets the collapsed group.