listview按列自动排序的一点补充
摘要: 使listview按列自动排序的例子网上有很多,MSDN上面也有,但是似乎都没指出这样一种情况:当我们点击列头进行排序时,如果里面有一子项不存在或者多项不存在,该怎么比较?前两天我就碰到了这样的情况,现在,我把自己的一些心得拿出来和大家分享.
大的就不用说了,我们都知道要实现listview的自定义排序,必须编写一个实现IComparer 接口的类,并将 ListViewItemSorter 属性设置为该类的一个对象.起初,我按照示例编写了一个自定义排序的类,并在listview的ColumnClick 事件下添加了相应代码.代码如下:
1.实现排序的类:
2.主窗体
大家仔细看这个Form1类,会发现listview1第四行只有两项,运行程序时当我们点击第一列,第二列进行排序是不会出问题,但是如果我们点击了第三列或者第四列的时候就会抛出ArgumentOutOfRangeException异常,仔细一看我们就明白了,原来第四项根本就只有2个子项,点击第三列或者第四列的时候,listItemA.SubItems[colNum]是根本不存在的,所以程序报错了.经过考虑,我的做法如下,首先判断listviewitem中是否有空项(即不存在的项),如果有则增加一项并将内容初始化为空,然后再进行比较.
在ColumnSort类中的Compare函数中插入如下代码:
现在我们就可以进行比较而不会出现刚才那个错误了.
小结:不知道大家看懂了不,多提点意见了,个人觉得这个还是有点实用的,欢迎指点.
大的就不用说了,我们都知道要实现listview的自定义排序,必须编写一个实现
1.实现排序的类:
public class ColumnSort:IComparer
{
private int colNum;
private bool bAscend = true;
public bool Ascend
{
get
{
return bAscend;
}
set
{
bAscend = value;
}
}
public ColumnSort(int sortColun)
{
this.colNum = sortColun;
}
public int Compare(object A, object B)
{
System.Windows.Forms.ListViewItem listItemA = (System.Windows.Forms.ListViewItem)A;
System.Windows.Forms.ListViewItem listItemB = (System.Windows.Forms.ListViewItem)B;
int result;
//对相邻的两项进行比较
result = String.Compare(listItemA.SubItems[colNum].ToString(), listItemB.SubItems[colNum].ToString());
if (bAscend == true)
return result;
else
return (-1) * result;
}
}
{
private int colNum;
private bool bAscend = true;
public bool Ascend
{
get
{
return bAscend;
}
set
{
bAscend = value;
}
}
public ColumnSort(int sortColun)
{
this.colNum = sortColun;
}
public int Compare(object A, object B)
{
System.Windows.Forms.ListViewItem listItemA = (System.Windows.Forms.ListViewItem)A;
System.Windows.Forms.ListViewItem listItemB = (System.Windows.Forms.ListViewItem)B;
int result;
//对相邻的两项进行比较
result = String.Compare(listItemA.SubItems[colNum].ToString(), listItemB.SubItems[colNum].ToString());
if (bAscend == true)
return result;
else
return (-1) * result;
}
}
2.主窗体
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.listView1.Items.Add("kandy");
this.listView1.Items[0].SubItems.Add("0");
this.listView1.Items[0].SubItems.Add("11");
this.listView1.Items[0].SubItems.Add("10");
this.listView1.Items.Add("list");
this.listView1.Items[1].SubItems.Add("1");
this.listView1.Items[1].SubItems.Add("22");
this.listView1.Items[1].SubItems.Add("44");
this.listView1.Items.Add("jsjlili");
this.listView1.Items[2].SubItems.Add("1");
this.listView1.Items[2].SubItems.Add("33");
this.listView1.Items.Add("ff");
this.listView1.Items[3].SubItems.Add("99");
//this.listView1.Items[4].SubItems.Add("0");
//this.listView1.Items
//this.listView1.Items[4].SubItems.Add("77");
}
private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
ColumnSort colSort = new ColumnSort(e.Column);
int iRow = this.listView1.Columns.Count;
int iCol = this.listView1.Items.Count;
colSort.Ascend = (this.listView1.Sorting == SortOrder.Ascending);
if (colSort.Ascend == true)
{
this.listView1.Sorting = SortOrder.Descending;
}
else
{
this.listView1.Sorting = SortOrder.Ascending;
}
//this.listView1.Sort();
this.listView1.ListViewItemSorter = colSort;
}
}
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.listView1.Items.Add("kandy");
this.listView1.Items[0].SubItems.Add("0");
this.listView1.Items[0].SubItems.Add("11");
this.listView1.Items[0].SubItems.Add("10");
this.listView1.Items.Add("list");
this.listView1.Items[1].SubItems.Add("1");
this.listView1.Items[1].SubItems.Add("22");
this.listView1.Items[1].SubItems.Add("44");
this.listView1.Items.Add("jsjlili");
this.listView1.Items[2].SubItems.Add("1");
this.listView1.Items[2].SubItems.Add("33");
this.listView1.Items.Add("ff");
this.listView1.Items[3].SubItems.Add("99");
//this.listView1.Items[4].SubItems.Add("0");
//this.listView1.Items
//this.listView1.Items[4].SubItems.Add("77");
}
private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
ColumnSort colSort = new ColumnSort(e.Column);
int iRow = this.listView1.Columns.Count;
int iCol = this.listView1.Items.Count;
colSort.Ascend = (this.listView1.Sorting == SortOrder.Ascending);
if (colSort.Ascend == true)
{
this.listView1.Sorting = SortOrder.Descending;
}
else
{
this.listView1.Sorting = SortOrder.Ascending;
}
//this.listView1.Sort();
this.listView1.ListViewItemSorter = colSort;
}
}
大家仔细看这个Form1类,会发现listview1第四行只有两项,运行程序时当我们点击第一列,第二列进行排序是不会出问题,但是如果我们点击了第三列或者第四列的时候就会抛出ArgumentOutOfRangeException异常,仔细一看我们就明白了,原来第四项根本就只有2个子项,点击第三列或者第四列的时候,listItemA.SubItems[colNum]是根本不存在的,所以程序报错了.经过考虑,我的做法如下,首先判断listviewitem中是否有空项(即不存在的项),如果有则增加一项并将内容初始化为空,然后再进行比较.
在ColumnSort类中的Compare函数中插入如下代码:
int iColA = listItemA.SubItems.Count;
int iColB= listItemB.SubItems.Count;
//判断listviewitem中是否有空项,如果有空项则将其置为空,然后再进行比较
if (iColA.CompareTo(iColB) > 0)
{
for (int i = 1; i <= iColA - iColB; i++)
{
listItemB.SubItems.Add("");
}
}
else
{
for (int j = 1; j <= iColB - iColA; j++)
{
listItemA.SubItems.Add("");
}
}
int iColB= listItemB.SubItems.Count;
//判断listviewitem中是否有空项,如果有空项则将其置为空,然后再进行比较
if (iColA.CompareTo(iColB) > 0)
{
for (int i = 1; i <= iColA - iColB; i++)
{
listItemB.SubItems.Add("");
}
}
else
{
for (int j = 1; j <= iColB - iColA; j++)
{
listItemA.SubItems.Add("");
}
}
现在我们就可以进行比较而不会出现刚才那个错误了.
小结:不知道大家看懂了不,多提点意见了,个人觉得这个还是有点实用的,欢迎指点.