Sorting in MAUI DataGrid (SfDataGrid)

18 Mar 202418 minutes to read

The SfDataGrid provides the built-in support to sort one or more columns by using the SfDataGrid.SortingMode property. When sorting is applied, the data grid automatically rearranges the data to match the current sort criteria. Sort the data by tapping the column header. Once sorting is applied, the data grid shows a sort icon in the respective column header indicating the sort direction.

To get start quickly with sorting in .NET MAUI DataGrid, you can check on this video:

Programmatic sorting

Sort the data programmatically by adding or removing the SortColumnDescription in SfDataGrid.SortColumnDescriptions property.

The SortColumnDescription object holds the following two properties:

  • ColumnName: The name of a column to be sorted.
  • SortDirection: An object of type ListSortDirection defines the sorting direction.
<syncfusion:SfDataGrid x:Name="sfDataGrid" ItemsSource="{Binding OrderInfoCollection}" >

    <syncfusion:SfDataGrid.SortColumnDescriptions>
        <syncfusion:SortColumnDescription ColumnName="OrderID" SortDirection="Ascending" />
    </syncfusion:SfDataGrid.SortColumnDescriptions>
</syncfusion:SfDataGrid>

Programmatical sorting .NET MAUI DataGrid

Different modes of sorting

SfDataGrid sorts the data against one or more columns based on the SfDataGrid.SortingMode property. The SortingMode contains the following properties:

  • Single - It allows to sort only one column at a time.
  • Multiple - It allows to sort more than one column at a time.
  • None - None of the columns can be sorted.

To apply the sort for multiple columns, tap the desired column headers after setting the SfDataGrid.SortingMode property to Multiple.

<syncfusion:SfDataGrid x:Name="sfDataGrid" SortingMode="Multiple" ItemsSource="{Binding OrderInfoCollection}" >
</syncfusion:SfDataGrid>

Multi sorting .NET MAUI DataGrid

Tri-state sorting

In addition, to sort the data in ascending or descending order, the SfDataGrid unsort the data in the original order by clicking the header again after sorting to descending order by setting the SfDataGrid.AllowTriStateSorting property to true. When this property is set, sorting in each column iterates through three sort states; ascending, descending, and unsort.

<syncfusion:SfDataGrid x:Name="sfDataGrid" SortingMode="Single" AllowTriStateSorting="True" ItemsSource="{Binding OrderInfoCollection}" >
</syncfusion:SfDataGrid>

Tri-state sorting .NET MAUI DataGrid

Show sort number

The SfDataGrid provides support to display the sequence numbers to denote the order of the column in which they are sorted during multiple columns sorting by setting the SfDataGrid.ShowSortNumbers is set to true. This is applicable when the SfDataGrid.SortingMode property is Multiple.

<syncfusion:SfDataGrid x:Name="sfDataGrid" SortingMode="Multiple" ShowSortNumbers="True" ItemsSource="{Binding OrderInfoCollection}" >
</syncfusion:SfDataGrid>

Sort with sequence numbers .NET MAUI DataGrid

Sort column in double tap

By default, the column gets sorted when the column header is clicked. This behavior can be changed to sort the column in a double-click action by setting the SfDataGrid.SortingGestureType property to DoubleTap.

<syncfusion:SfDataGrid x:Name="sfDataGrid" SortingMode="Single" SortingGestureType="DoubleTap" ItemsSource="{Binding OrderInfoCollection}" >
</syncfusion:SfDataGrid>

Sorting events

The data grid provides the following events for the sorting functionality:

AddedItems: Gets the collection of the SortColumnDescription objects that are added to the SortColumnDescriptions collection for sorting.
RemovedItems: Gets the collection of the SortColumnDescription objects that are removed from the SortColumnDescriptions collection.

The following code sample demonstrates how to cancel sorting for a particular column by using the SortColumnsChanging event,

<syncfusion:SfDataGrid x:Name="sfDataGrid" SortingMode="Single" SortColumnsChanging="sfDataGrid_SortColumnsChanging" ItemsSource="{Binding OrderInfoCollection}" >
</syncfusion:SfDataGrid>
private void sfDataGrid_SortColumnsChanging(object sender, DataGridSortColumnsChangingEventArgs e)
{
    if (e.AddedItems[0].ColumnName == "OrderID")
    {
        e.Cancel = true;
    }
}

Disable sorting for auto generated columns

During auto-generating columns, disable sorting for an individual column by customizing the e.Column.AllowSorting property to false that comes from the SfDataGrid.AutoGeneratingColumn event. The event will be invoked when the column is auto-generated.

<syncfusion:SfDataGrid x:Name="sfDataGrid" AutoGeneratingColumn="sfDataGrid_AutoGeneratingColumn" SortingMode="Single" ItemsSource="{Binding OrderInfoCollection}" >
</syncfusion:SfDataGrid>
private void sfDataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgse)
{
    if (e.Column.MappingName == "OrderID")
    {
        e.Column.AllowSorting = false;
    }
}

Disable sorting for manually defined columns

The SfDataGrid disables sorting for an individual column by setting the DataGridColumn.AllowSorting property to false. The default value of this property is true.

<syncfusion:SfDataGrid x:Name="sfDataGrid" AutoGenerateColumnsMode="None" SortingMode="Single"ItemsSource="{Binding OrderInfoCollection}" >
    <syncfusion:SfDataGrid.Columns>
        <syncfusion:DataGridNumericColumn HeaderText="Order ID" AllowSorting="False" MappingName="OrderID" />
        <syncfusion:DataGridTextColumn HeaderText="Customer ID" MappingName="CustomerID" />
        <syncfusion:DataGridTextColumn HeaderText="Customer" MappingName="Customer" />
        <syncfusion:DataGridTextColumn HeaderText="Ship City" MappingName="ShipCity" />
        <syncfusion:DataGridTextColumn HeaderText="Ship Country" MappingName="ShipCountry" />
    </syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>

Custom sorting

The SfDataGrid provides support to sort columns based on custom logic when the standard sorting techniques do not meet the requirements SortComparer objects to the SfDataGrid.SortComparers collection.

The SortComparer object contains the following properties:

  • PropertyName: The MappingName of the column that applies custom sorting.
  • Comparer: Gets or sets the custom comparer that implements the IComparer and ISortDirection interfaces.

The following example shows how to sort the columns based on the length of their cell values:

<ContentPage
             xmlns:comparer="clr-namespace:GettingStarted.Comparer"
             xmlns:data="clr-namespace:Syncfusion.Maui.Data;assembly=Syncfusion.Maui.Data"
             xmlns:syncfusion="clr-namespace:Syncfusion.Maui.DataGrid;assembly=Syncfusion.Maui.DataGrid">

    <ContentPage.Resources>
        <ResourceDictionary>
            <comparer:CustomSortComparer x:Key="comparer" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <ContentPage.BindingContext>
        <local:ViewModel/>
    </ContentPage.BindingContext>

    <syncfusion:SfDataGrid x:Name="sfDataGrid"  SortingMode="Single" ItemsSource="{Binding OrderInfoCollection}" >
        <syncfusion:SfDataGrid.SortComparers>
            <data:SortComparer Comparer="{StaticResource comparer}" PropertyName="CustomerID" />
        </syncfusion:SfDataGrid.SortComparers>

        <syncfusion:SfDataGrid.SortColumnDescriptions>
            <syncfusion:SortColumnDescription ColumnName="CustomerID" SortDirection="Ascending"/>
        </syncfusion:SfDataGrid.SortColumnDescriptions>
    </syncfusion:SfDataGrid>
</ContentPage>
public class CustomSortComparer : IComparer<object>, ISortDirection
{
    private int nameX;
    private int nameY;

    private ListSortDirection sortDirection;

    public ListSortDirection SortDirection
    {
        get { return this.sortDirection; }
        set { this.sortDirection = value; }
    }

    public int Compare(object x, object y)
    {
        if (x!.GetType() == typeof(OrderInfo))
        { 
            this.nameX = ((OrderInfo)x!).CustomerID.Length;
            this.nameY = ((OrderInfo)y!).CustomerID.Length;
        }
        else
        {
            this.nameX = x.ToString()!.Length;
            this.nameY = y!.ToString()!.Length;
        }
        if (this.nameX.CompareTo(this.nameY) > 0)
        {
            return this.SortDirection == ListSortDirection.Ascending ? 1 : -1;
        }
        else if (this.nameX.CompareTo(this.nameY) == -1)
        {
            return this.SortDirection == ListSortDirection.Ascending ? -1 : 1;
        }
        else
        {
            return 0;
        }
    }
}

Change sort icon color

The default sort icon color can be customized by setting the DataGridStyle.SortIconColor property.

<syncfusion:SfDataGrid x:Name="sfDataGrid"
                        ItemsSource="{Binding OrderInfoCollection}" >
        <syncfusion:SfDataGrid.DefaultStyle>
                <syncfusion:DataGridStyle SortIconColor="DodgerBlue" />
        </syncfusion:SfDataGrid.DefaultStyle>
        <syncfusion:SfDataGrid.Columns>
                    <syncfusion:DataGridTextColumn MappingName="OrderID"
                              AllowSorting="True"
                              HeaderText="Order ID" />
                    <syncfusion:DataGridTextColumn MappingName="CustomerID"
                              HeaderText="Customer ID" />
                    <syncfusion:DataGridTextColumn MappingName="ShipCountry "
                              HeaderText="Ship Country " />
        </syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>

Sort icon customization in MAUI DataGrid

Load sort icon through template

The SfDataGrid uses an icon to indicate the ascending and descending states of sorting. You can personalize the sorting icon by using the SfDataGrid.SortIconTemplate property. This property allows you to define a custom template that appears in its regular form when the sort is in ascending order. It will rotate downward when the sort is in descending order. To implement this, refer to the following code snippet:

<syncfusion:SfDataGrid ItemsSource="{Binding OrderInfoCollection}"
                            x:Name="dataGrid"
                            SortingMode="Multiple"
                            >
        <syncfusion:SfDataGrid.SortIconTemplate>
                <DataTemplate>
                    <Image Source="expand_less.png"/>
                </DataTemplate>
        </syncfusion:SfDataGrid.SortIconTemplate>
</syncfusion:SfDataGrid>
this.dataGrid.SortingMode = DataGridSortingMode.Multiple;
dataGrid.SortIconTemplate = new DataTemplate(() =>
        {
            var imageView1 = new Image()
            {
                Source = "expand_less.png",
                Aspect = Aspect.AspectFit,
            };
            return imageView1;
        });

DataGrid with sort icon template

Load sort icon through template selector

When choosing a SortIconTemplate as a DataTemplateSelector, you have the option to supply distinct templates for both the ascending and descending states of the sorting.

<ContentPage.Resources>
        <ResourceDictionary>
            <DataTemplate x:Key="Descending">
                <Image>
                    <Image.Source>
                        <FontImageSource Color="Red" Glyph="&#xe701;"
                                 FontFamily="{OnPlatform iOS=MauiMaterialAssets, MacCatalyst=MauiMaterialAssets, WinUI=MauiMaterialAssets.ttf#, Android=MauiMaterialAssets.ttf#}"
                                 Size="44" />
                    </Image.Source>
                </Image>
            </DataTemplate>
            <DataTemplate x:Key="Ascending">
                <Image>
                    <Image.Source>
                        <FontImageSource Color="Green" Glyph="&#xe702;"
                                 FontFamily="{OnPlatform iOS=MauiMaterialAssets, MacCatalyst=MauiMaterialAssets, WinUI=MauiMaterialAssets.ttf#, Android=MauiMaterialAssets.ttf#}"
                                 Size="44" />
                    </Image.Source>
                </Image>
            </DataTemplate>
        </ResourceDictionary>
    </ContentPage.Resources>
<ContentPage.Content>
<syncfusion:SfDataGrid  ItemsSource="{Binding OrderInfoCollection}"
                            x:Name="dataGrid"
                            SortingMode="Multiple"
                            >
        <syncfusion:SfDataGrid.SortIconTemplate >
            <local:SortIconTemplate AscendingTemplate="{StaticResource Ascending }" DescendingTemplate="{StaticResource Descending}" />
        </syncfusion:SfDataGrid.SortIconTemplate>
</syncfusion:SfDataGrid>
<ContentPage.Content>
public class SortIconTemplate : DataTemplateSelector
{
    public DataTemplate AscendingTemplate { get; set; }

    public DataTemplate DescendingTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {      
        var description = item as SortColumnDescription;
        if (description == null)
        {
            return null;
        }

        if (description.SortDirection == System.ComponentModel.ListSortDirection.Ascending)
        {
            return AscendingTemplate;
        }
        else
        {
            return DescendingTemplate;
        }
    }
}

DataGrid with sort template selector