今天写.Net大作业时,有一个功能是点击ListView的每列的表头时,对整个表的信息按该列进行升序或降序排序。我的这个表的数据比较特殊,里面有string,int,float三种数据类型,而C#的ListView默认的比较方法只能把数据当做string来处理,这样的话当对int型数据排序时10就会在2前面,对float型数据排序时100.99就会在98.99前面。我在网上找了一些代码,做了一些修改,现在可以完美地处理这三种数据。
原始数据图片:
当点击RefMarque列时,如果按默认的string类型来排序,结果如下:
可以发现10排在了2前面,因为它是先比较第一位,按ASCII码排序,1就在2前面。
对ListView排序算法进行了修改和完善。代码如下:
private void listView1_ColumnClick(object sender, ColumnClickEventArgs e){
if (e.Column != sortColumn){
// Set the sort column to the new column.
sortColumn = e.Column;
// Set the sort order to ascending by default.
listView1.Sorting = SortOrder.Ascending;
}else{
// Determine what the last sort order was and change it.
if (listView1.Sorting == SortOrder.Ascending){
listView1.Sorting = SortOrder.Descending;
}else{
listView1.Sorting = SortOrder.Ascending;
}
}
// Call the sort method to manually sort.
listView1.Sort();
// Set the ListViewItemSorter property to a new ListViewItemComparer
// object.
this.listView1.ListViewItemSorter = new ListViewItemComparer(e.Column, listView1.Sorting);
}
比较用的类
class ListViewItemComparer : IComparer{
private int col;
private SortOrder order;
public ListViewItemComparer()
{
col = 0;
order = SortOrder.Ascending;
}
public ListViewItemComparer(int column, SortOrder order)
{
col = column;
this.order = order;
}
public int Compare(object x, object y)
{
int returnVal = -1;
float a = 0, b = 0;
if (float.TryParse(((ListViewItem)x).SubItems[col].Text, out a) && float.TryParse(((ListViewItem)y).SubItems[col].Text, out b))
{
returnVal = a >= b ? (a == b ? 0 : 1) : -1;
if (order == SortOrder.Descending) {
returnVal *= -1;
}
}
else{
returnVal = String.Compare(((ListViewItem)x).SubItems[col].Text,
((ListViewItem)y).SubItems[col].Text);
// Determine whether the sort order is descending.
if (order == SortOrder.Descending){
// Invert the value returned by String.Compare.
returnVal *= -1;
}
}
return returnVal;
}
}
如果要处理的数据里没有float类型,上面类里的a,b可以定义成int型,下面的float.TryParse换成int.TryParse