This code is very slow however.
Here’s an improved version which also handles sorting of numbers.
First create a static Dictionary in your MainForm, like this:
internal static Dictionary<int, ListViewColumnSorter.cDataType> columnType = new Dictionary<int,ListViewColumnSorter.cDataType>();
cDataType
is an enum:
public enum cDataType
public enum cDataType
{
number, datetime, text
}
When re-loading your ListView, or when changing the columns, clear the Dictionary, because the data type of the column can change.
public int Compare(object x, object y)
{
int compareResult;
ListViewItem listviewX, listviewY;
// Cast the objects to be compared to ListViewItem objects
listviewX = (ListViewItem)x;
listviewY = (ListViewItem)y;
// Compare the two items
//Determine data type of object
string objectX = listviewX.SubItems[ColumnToSort].Text;
string objectY = listviewY.SubItems[ColumnToSort].Text;
cDataType dType = cDataType.text;
if (!MainForm.columnType.TryGetValue(ColumnToSort, out dType))
{
long tempLong;
DateTime tempDateTime;
if (Int64.TryParse(objectX, out tempLong))
{
MainForm.columnType.Add(ColumnToSort, cDataType.number);
}
else if (DateTime.TryParse(objectX, out tempDateTime))
{
MainForm.columnType.Add(ColumnToSort, cDataType.datetime);
}
else
{
MainForm.columnType.Add(ColumnToSort, cDataType.text);
}
}
switch (MainForm.columnType[ColumnToSort])
{
case cDataType.number:
compareResult = ObjectCompare.Compare(Convert.ToInt64(objectX), Convert.ToInt64(objectY));
break;
case cDataType.datetime:
compareResult = ObjectCompare.Compare(DateTime.Parse(objectX), DateTime.Parse(objectY));
break;
default:
compareResult = ObjectCompare.Compare(objectX, objectY);
break;
}
// Calculate correct return value based on object comparison
if (OrderOfSort == SortOrder.Ascending)
{
// Ascending sort is selected, return normal result of compare operation
return compareResult;
}
else if (OrderOfSort == SortOrder.Descending)
{
// Descending sort is selected, return negative result of compare operation
return (-compareResult);
}
else
{
// Return '0' to indicate they are equal
return 0;
}
}

@Arnout: Thanks for your suggestions and improvements.
ReplyDelete