This article demonstrates how to apply sorting on objects. It is useful when you need to apply sorting on objects e.g. Object Person(Name, Age) and you want to apply sorting on Person->Name, or you may wish to apply sorting on multiple fields i.e. Person->name DESC + person->age DESC.
It is very useful when you want to apply multiple column sorting on GridViews with ObjectDataSource.
Using Reflection its very easy to sort objects. I had used Lists to sort objects and ObjectComparer class is inherited from IComparer
ObjectComparer supports Single as well as Multiple sorting.
Person[] personArray = new Person[] {
new Person("Ritesh", 26),
new Person("Arpan", 20),
new Person("Arpan", 23),
new Person("Hiren", 22),
new Person("Ankit", 22),
new Person("Dhaval", 23),
new Person("Gaurav", 25)
};
Array.Sort(personArray, new ObjectComparer<Person>("Name"));
Array.Sort(personArray, new ObjectComparer<Person>("Name DESC, Age ASC",true));
ObjectComparer.cs
[Serializable]
public class ObjectComparer<ComparableObject> : IComparer<ComparableObject>
{
#region Constructor
public ObjectComparer()
{
}
public ObjectComparer(string p_propertyName)
{
this.PropertyName = p_propertyName;
}
public ObjectComparer(string p_propertyName, bool p_MultiColumn)
{
this.PropertyName = p_propertyName;
this.MultiColumn = p_MultiColumn;
}
#endregion
#region Property
private bool _MultiColumn;
public bool MultiColumn
{
get { return _MultiColumn; }
set { _MultiColumn = value; }
}
private string _propertyName;
public string PropertyName
{
get { return _propertyName; }
set { _propertyName = value; }
}
#endregion
#region IComparer<ComparableObject> Members
public int Compare(ComparableObject x, ComparableObject y)
{
Type t = x.GetType();
if (_MultiColumn) {
string[] sortExpressions = _propertyName.Trim().Split(',');
for (int i = 0; i < sortExpressions.Length; i++)
{
string fieldName, direction = "ASC";
if (sortExpressions[i].Trim().EndsWith(" DESC"))
{fieldName = sortExpressions[i].Replace(" DESC", "").Trim();
direction = "DESC";
}
else
{
fieldName = sortExpressions[i].Replace(" ASC", "").Trim();
}
PropertyInfo val = t.GetProperty(fieldName);
if (val != null)
{
int iResult = Comparer.DefaultInvariant.Compare(val.GetValue(x, null), val.GetValue(y, null));
if (iResult != 0)
{
if (direction == "DESC")
{
return -iResult;
}
else
{
return iResult;
}
}
}
else
{
throw new Exception(fieldName + " is not a valid property to sort on. It doesn't exist in the Class.");
}
}
return 0;
}
else
{
PropertyInfo val = t.GetProperty(this.PropertyName);
if (val != null)
{
return Comparer.DefaultInvariant.Compare(val.GetValue(x, null), val.GetValue(y, null));
}
else
{
throw new Exception(this.PropertyName + " is not a valid property to sort on. It doesn't exist in the Class.");
}
}
}
#endregion
}