Use Custom Comparer to Speed up the Sorting in RadGridView
| Date Posted | Product | Author |
|---|---|---|
| May 21, 2015 | RadGridView for WinForms | Dimitar Karamfilov |
Problem
When sorting the RadGridView logic should retrieve all object properties by using reflection. This is needed because the sorting must work with different kind of objects and should be able to compare them. Taking the property value with reflection is slow (this can be noted when you have large amount of rows in the grid) and can be avoided by using a custom comparer where the items are directly casted to the respective objects.
Solution
First, you need to implement the custom comparer class. This class should implement the IComparer<GridViewRowInfo> interface. This interface has only one method called Compare. It takes two arguments and their type is GridViewRowInfo (In general the class should be able to compare two rows and return the result).
In addition you should have access to the SortDescritors collection of the grid view. This can be achieved by passing it to group comparer constructor. This will allow you to compare the rows according to all columns sort descriptors and the current sort direction.
The CompareDataItems method should be able to compare all data object properties. This way the user will be able to sort each column.
public class CustomComparer : IComparer<GridViewRowInfo>
{
private SortDescriptorCollection sortDescriptors;
public CustomComparer(SortDescriptorCollection sortDescriptors)
{
this.sortDescriptors = sortDescriptors;
}
public int Compare(GridViewRowInfo x, GridViewRowInfo y)
{
GridItem item1 = (GridItem)x.DataBoundItem;
GridItem item2 = (GridItem)y.DataBoundItem;
int result = 0;
for (int i = 0; i < this.sortDescriptors.Count; i++)
{
result = this.CompareDataItems(item1, item2, this.sortDescriptors[i].PropertyName, this.sortDescriptors[i].Direction == ListSortDirection.Ascending);
if (result != 0)
{
return result;
}
}
return result;
}
private int CompareDataItems(GridItem x, GridItem y, string propertyName, bool ascending)
{
int asc = (ascending) ? 1 : -1;
switch (propertyName)
{
case "TextValue":
return x.TextValue.CompareTo(y.TextValue) * asc;
case "IntValue":
return x.IntValue.CompareTo(y.IntValue) * asc;
}
return 0;
}
}
To use the class assign new instance to the SortComparer property:
radGridView1.MasterTemplate.SortComparer = new CustomComparer(this.radGridView1.SortDescriptors);
You can use the following code to complete the example and test the sorting:
public partial class RadForm1 : Telerik.WinControls.UI.RadForm
{
Random rnd = new Random();
BindingList<GridItem> data;
public RadForm1()
{
InitializeComponent();
data = new BindingList<GridItem>();
for (int i = 0; i < 100000; i++)
{
data.Add(new GridItem("Text " + rnd.Next(100), i));
}
radGridView1.DataSource = data;
}
}
public class GridItem
{
public string TextValue { get; set; }
public int IntValue { get; set; }
public GridItem(string textValue, int intValue)
{
this.TextValue = textValue;
this.IntValue = intValue;
}
}
A complete solution in C# and VB.NET can be found here.