New to Telerik UI for WPF? Download free 30-day trial

Custom Sorting

Although RadGridView provides a fully functional sorting mechanism, it can sometimes be slow or ineffective, compared to other sorting mechanisms (database server, LINQ extension methods, manually working with the SortDescriptors collection etc.). To benefit from them you have to bypass the existing sorting functionality of RadGridView.

You can set the SortMemberPath property of the column to specify the name of the property the data in the column will be sorted by.

Some other ways to customize the sort are listed below:

Custom Sorting with IComparable

In order to be able to sort the items in a way you define, the bound business object could implement IComparable interface. Thus you will tell RadGridView how to sort the items. Since it respects this interface, it will sort the items depending on the logic you implement.

You can check some sample code on our Custom Sorting with IComparable demo.

It demonstrates using the IComparable interface to sort items.

You can also find the Sorting Strings as Numbers topic.

Custom Sorting with Generic SortDescriptor

You can also change the sorting algorithm through applying a Generic Sort Descriptor.

Custom Sorting handling Sorting Event

To do so you can use the Sorting event. As a start you need to attach an event handler to it:

this.radGridView.Sorting += this.radGridView_Sorting; 
AddHandler Me.radGridView.Sorting, AddressOf Me.radGridView_Sorting 

When performing a custom sorting, you need to set the IsCustomSortingEnabled property of the column to True. This is required in order to preserve the sorting direction of the column when another data operation (such as sorting, filtering or grouping) is performed.

Take a look at the GridViewSortingEventArgs argument of the event handler. There are a few properties that require your attention:

  • DataControl - this one holds the instance of RadGridView owning the column that was clicked and is going to be sorted.

  • Cancel - this boolean property defines whether the internal handling of the sorting event should be canceled. The default value is False, which means that the event will be handled internally by RadGridView and the built-in sorting functionality will be executed. If you set it to True the event won't be handled by RadGridView and the built-in sorting functionality will be bypassed.

  • OldSortingState - defines the current sorting state of the column being sorted.

  • NewSortingState - defines the new sorting state of the column and controls the sorting indicator of the column's header. Even if you don't want the built-in sorting functionality to be executed you have to properly set this property, otherwise the visual state of the sort indicator won't match the sort state of the data.

  • Column - the gridview column which is being sorted.

For the example you have to sort the ItemsSource of RadGridView on Sorting event handler using LINQ extension methods. For that purpose be sure that you are using System.Linq namespace.

The first thing to do is to get the value of RadGridView.ItemsSource and assure that it is not null. In the Sorting event handler you can add the following lines of code:

private void radGridView_Sorting(object sender, GridViewSortingEventArgs e) 
{ 
    //Gets the value of the ItemsSource property as IEnumerable. 
    IEnumerable<Employee> employees = e.DataControl.ItemsSource as IEnumerable<Employee>; 
    //Checks if the value of the collection is null. 
    if (employees == null) 
    { 
        e.Cancel = true; 
        return; 
    } 
} 
Private Sub radGridView_Sorting(ByVal sender As Object, ByVal e As GridViewSortingEventArgs) 
    'Gets the value of the ItemsSource property as IEnumerable. 
    Dim employees As IEnumerable(Of Employee) = TryCast(e.DataControl.ItemsSource, IEnumerable(Of Employee)) 
 
    'Checks if the value of the collection is null. 
    If employees Is Nothing Then 
        e.Cancel = True 
        Exit Sub 
    End If 
End Sub 

Next you have to check the value of the current sorting direction. To do that use OldSortingState property of GridViewSortingEventArgs, adding the following lines of code to the sorting event handler:

//If the sorting state is none, sort the items ascending. 
if (e.OldSortingState == SortingState.None) 
{ 
    e.NewSortingState = SortingState.Ascending; 
} 
//If the sorting state is ascending, sort the items descending. 
else if (e.OldSortingState == SortingState.Ascending) 
{ 
    e.NewSortingState = SortingState.Descending; 
} 
//If the sorting state is descending, apply default sorting to the items. 
else 
{ 
    e.NewSortingState = SortingState.None; 
} 
'If the sorting state is none, sort the items ascending. 
If e.OldSortingState = SortingState.None Then 
    e.NewSortingState = SortingState.Ascending 
    'If the sorting state is ascending, sort the items descending. 
ElseIf e.OldSortingState = SortingState.Ascending Then 
    e.NewSortingState = SortingState.Descending 
    'If the sorting state is descending, apply default sorting to the items. 
Else 
    e.NewSortingState = SortingState.None 
End If 

You can see that after determining the sorting state, NewSortingState property is set to match the new sorting state.

To sort the employees collection use OrderBy and OrderByDescending extension methods provided by System.Linq namespace. The extension methods work with lambda expressions.

//Via the SortPropertyName value get  
//the value of the property to sort your data by. 
employees = employees.OrderBy(employee => employee.GetType() 
                                                  .GetProperty((e.Column as GridViewDataColumn).GetDataMemberName()) 
                                                  .GetValue(employee, null)); 
'Via the SortPropertyName value get  
'the value of the property to sort your data by. 
employees = employees.OrderBy(Function(employee) employee.GetType().GetProperty((TryCast(e.Column, GridViewDataColumn)).GetDataMemberName()).GetValue(employee, Nothing)) 
' #endregion 
 
'#region gridview-sorting-custom_9 
e.DataControl.ItemsSource = employees.ToList() 
e.Cancel = True 

Do the same with OrderByDescending extension method. In the end, set RadGridView.ItemsSource to the sorted employees collection and set the Cancel property of the RadGridViewEventArgs to True , so the built-in sorting functionality would be bypassed.

e.DataControl.ItemsSource = employees.ToList(); 
e.Cancel = true; 
e.DataControl.ItemsSource = employees.ToList() 
e.Cancel = True 

Here is the final code that should represent Sorting event handler.

private void CustomSortingGrid_Sorting(object sender, GridViewSortingEventArgs e) 
{ 
    //Gets the value of the ItemsSource property as IEnumerable. 
    IEnumerable<Employee> employees = e.DataControl.ItemsSource as IEnumerable<Employee>; 
    //Checks if the value of the collection is null. 
    if (employees == null) 
    { 
        e.Cancel = true; 
        return; 
    } 
    //If the sorting state is none, sort the items ascending. 
    if (e.OldSortingState == SortingState.None) 
    { 
        e.NewSortingState = SortingState.Ascending; 
        employees = employees.OrderBy(employee => employee.GetType() 
                                                          .GetProperty((e.Column as GridViewDataColumn).GetDataMemberName()) 
                                                          .GetValue(employee, null)); 
    } 
    //If the sorting state is ascending, sort the items descending. 
    else if (e.OldSortingState == SortingState.Ascending) 
    { 
        e.NewSortingState = SortingState.Descending; 
        employees = employees.OrderByDescending(employee => employee.GetType() 
                                                           .GetProperty((e.Column as GridViewDataColumn).GetDataMemberName()) 
                                                           .GetValue(employee, null)); 
    } 
    //If the sorting state is descending, apply default sorting to the items. 
    else 
    { 
        e.NewSortingState = SortingState.None; 
        employees = employees.OrderBy(employee => employee.EmployeeID); 
    } 
    //Set the sorted collection as source of the RadGridView 
    e.DataControl.ItemsSource = employees.ToList(); 
    e.Cancel = true; 
} 
Private Sub CustomSortingGrid_Sorting(ByVal sender As Object, ByVal e As GridViewSortingEventArgs) 
    'Gets the value of the ItemsSource property as IEnumerable. 
    Dim employees As IEnumerable(Of Employee) = TryCast(e.DataControl.ItemsSource, IEnumerable(Of Employee)) 
 
    'Checks if the value of the collection is null. 
    If employees Is Nothing Then 
        e.Cancel = True 
        Exit Sub 
    End If 
 
    'If the sorting state is none, sort the items ascending. 
    If e.OldSortingState = SortingState.None Then 
        e.NewSortingState = SortingState.Ascending 
        employees = employees.OrderBy(Function(employee) employee.GetType.GetProperty(TryCast(e.Column, GridViewDataColumn).GetDataMemberName()).GetValue(employee, Nothing)) 
        'If the sorting state is ascending, sort the items descending. 
    ElseIf e.OldSortingState = SortingState.Ascending Then 
        e.NewSortingState = SortingState.Descending 
        employees = employees.OrderByDescending(Function(employee) employee.GetType.GetProperty(TryCast(e.Column, GridViewDataColumn).GetDataMemberName()).GetValue(employee, Nothing)) 
    Else 
        'If the sorting state is descending, apply default sorting to the items. 
        e.NewSortingState = SortingState.None 
        employees = employees.OrderBy(Function(employee) employee.EmployeeID) 
    End If 
 
    'Set the sorted collection as source of the RadGridView 
    e.DataControl.ItemsSource = employees.ToList() 
    e.Cancel = True 
End Sub 

The same technique is not only usable with LINQ extension methods and RadGridView.ItemsSource__. You can implement whatever logic you like for getting data and sorting it. This is just a simple example that clarifies the logic around the implementation of the custom sorting and not the sorting functionality itself.

Another example for custom sorting is the multi-column sorting, which is described in the Multi-column Sorting topic.

Sort Group by Aggregate

You can download a runnable project on how to sort a group by defined aggregate functions from our online SDK repository: SortGroupByAggregate.

Sort Group by Different Property

You can download a runnable project on how to sort a group by a different property from our online SDK repository: SortGroupByDifferentProperty.

You can also find SDK Samples Browser that provides a more convenient approach in exploring and executing the examples in the Telerik XAML SDK repository.

See Also

In this article