Hi Raghu,
Based on my understanding, you want to sort a ArrayList which contains some custom objects. The custom object has two properties: FirstName and LastName. Please feel free to tell me if I misunderstood you.
To sort an ArrayList, we can call the Sort method and pass a parameter of type IComparer. In this way, the root issue is how to pass a parameter of type IComparer. We need to create a new class which implements IComparer to change the default compare behavior and make the comparing result as what we want.
The code snippet below shows how to create a general comparer class to compare custom objects.
Custom comparer class:
public class MyComparable<T> : Comparer<T>
{
//The list contains the property names need to be compared.
private List<string> _sortProperties = new List<string>();
public List<string> SortProperties { get { return _sortProperties; } }
//If the sort type is ascending or descending
private bool _isAsc = true;
public bool IsAsc { set { _isAsc = value; } get { return _isAsc; } }
public override int Compare(T x, T y)
{
int compareResult = 0;
if (x != null && y != null)
{
foreach (string pName in _sortProperties)
{
PropertyInfo pInfo = typeof(T).GetProperty(pName);
if (pInfo != null)
{
//Get values of the property.
//The value of X.
object xVal = pInfo.GetValue(x, null);
//The value of Y.
object yVal = pInfo.GetValue(y, null);
//Compare the values.
compareResult = CompareValue(xVal, yVal, pInfo);
//If the the values are not equal, return; otherwise, continue comparing.
if (compareResult != 0)
break;
}
}
}
return compareResult;
}
private int CompareValue(object xVal, object yVal, PropertyInfo p)
{
int res = 0;
if (p != null)
{
Type pType = p.PropertyType;
bool xHasVal = true;
bool yHasVal = true;
//Check if the property is nullable and get its value.
if (pType.IsGenericType && (pType.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
//Check if the nullable object has value.
xHasVal = (bool)(pType.GetProperty("HasValue").GetValue(xVal, null));
yHasVal = (bool)(pType.GetProperty("HasValue").GetValue(yVal, null));
//If it has value, get the value.
if (xHasVal)
xVal = pType.GetProperty("Value").GetValue(xVal, null);
else
xVal = null;
if (yHasVal)
yVal = pType.GetProperty("Value").GetValue(yVal, null);
else
yVal = null;
pType = pType.GetGenericArguments()[0];//Get the true value type of nullable type.
}
if (xHasVal && yHasVal)
{
foreach (Type pInterface in pType.GetInterfaces())
{
if (pInterface == typeof(IComparable))
{
//Call CompareTo method of IComparable.
res = (xVal as IComparable).CompareTo(yVal as IComparable);
break;//Ciomparing finished.
}
else if (pInterface.IsGenericType && (pInterface.GetGenericTypeDefinition() == typeof(IComparable<>)))
{
//Call CompareTo method of Compare<T>
Type paramType = pInterface.GetGenericArguments()[0];//type of T
MethodInfo compareMethod = pInterface.GetMethod("CompareTo", new Type[] { paramType });//Get method
//Execute the method.
res = (int)(compareMethod.Invoke(xVal, new object[] { yVal }));
break;//Comparing finished.
}
}
}
else
{
if ((xHasVal == false) && (yHasVal == false))
res = 0;
else if ((xHasVal == false) && (yHasVal == true))
res = -1;
else if ((xHasVal == true) && (yHasVal == false))
res = 1;
}
}
return IsAsc ? res : -res;//Change the result according to the sort type.
}
}
This is the code snippet about the custom object and how to use the custom comparer class to sort the data source of the DataGridView:
Custom object:
public class People
{
public string FirstName { set; get; }
public string LastName { set; get; }
}
How to sort the data source:
ArrayList arrList = this.dataGridView1.DataSource as ArrayList;
MyComparable<People> peopleCompare = new MyComparable<People>();
peopleCompare.SortProperties.Add("FirstName");
peopleCompare.SortProperties.Add("LastName");
arrList.Sort(peopleCompare);
this.dataGridView1.Refresh();
These are some links:
IComparer: http://msdn.microsoft.com/en-us/library/system.collections.icomparer.aspx.
Comparer<T>: http://msdn.microsoft.com/en-us/library/cfttsh47.aspx.
Let me know if this helps.
Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.