C#winform点击ListView列标题进行排序
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Text.RegularExpressions; 6 using System.Windows.Forms; 7 8 namespace Common 9 { 10 /// <summary> 11 /// 点击列标题,对ListView自动排序功能 12 /// </summary> 13 public class ListViewHelper 14 { 15 /// <summary> 16 /// 点击列标题,对ListView列排序 17 /// </summary> 18 /// <param name="sender"></param> 19 /// <param name="e"></param> 20 public static void ListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e) 21 { 22 System.Windows.Forms.ListView lv = sender as System.Windows.Forms.ListView; 23 // 检查点击的列是不是现在的排序列. 24 if (e.Column == (lv.ListViewItemSorter as ListViewColumnSorter).SortColumn) 25 { 26 // 重新设置此列的排序方法. 27 if ((lv.ListViewItemSorter as ListViewColumnSorter).Order == SortOrder.Ascending) 28 { 29 (lv.ListViewItemSorter as ListViewColumnSorter).Order = SortOrder.Descending; 30 } 31 else 32 { 33 (lv.ListViewItemSorter as ListViewColumnSorter).Order = SortOrder.Ascending; 34 } 35 } 36 else 37 { 38 // 设置排序列,默认为正向排序 39 (lv.ListViewItemSorter as ListViewColumnSorter).SortColumn = e.Column; 40 (lv.ListViewItemSorter as ListViewColumnSorter).Order = SortOrder.Ascending; 41 } 42 // 用新的排序方法对ListView排序 43 lv.Sort(); 44 } 45 } 46 47 /// <summary> 48 /// 点击列标题,对ListView列排序功能,继承自IComparer 49 /// </summary> 50 public class ListViewColumnSorter : System.Collections.IComparer 51 { 52 #region 成员变量 53 /// <summary> 54 /// 指定按照哪个列排序 55 /// </summary> 56 private int ColumnToSort; 57 58 /// <summary> 59 /// 指定排序的方式 60 /// </summary> 61 private System.Windows.Forms.SortOrder OrderOfSort; 62 63 /// <summary> 64 /// 声明CaseInsensitiveComparer类对象 65 /// </summary> 66 private System.Collections.CaseInsensitiveComparer ObjectCompare; 67 #endregion 68 69 #region 属性 70 /// <summary> 71 /// 获取或设置按照哪一列排序. 72 /// </summary> 73 public int SortColumn 74 { 75 set 76 { 77 ColumnToSort = value; 78 } 79 get 80 { 81 return ColumnToSort; 82 } 83 } 84 85 /// <summary> 86 /// 获取或设置排序方式. 87 /// </summary> 88 public System.Windows.Forms.SortOrder Order 89 { 90 set 91 { 92 OrderOfSort = value; 93 } 94 get 95 { 96 return OrderOfSort; 97 } 98 } 99 #endregion 100 101 #region 构造函数 102 /// <summary> 103 /// 构造函数 104 /// </summary> 105 public ListViewColumnSorter() 106 { 107 // 默认按第一列排序 108 ColumnToSort = 0; 109 // 排序方式为不排序 110 OrderOfSort = System.Windows.Forms.SortOrder.Ascending; 111 // 初始化CaseInsensitiveComparer类对象 112 ObjectCompare = new System.Collections.CaseInsensitiveComparer(); 113 } 114 #endregion 115 116 #region 公有方法 117 /// <summary> 118 /// 重写IComparer接口. 119 /// </summary> 120 /// <param name="x">要比较的第一个对象</param> 121 /// <param name="y">要比较的第二个对象</param> 122 /// <returns>比较的结果.如果相等返回0,如果x大于y返回1,如果x小于y返回-1</returns> 123 public int Compare(object x, object y) 124 { 125 int compareResult; 126 System.Windows.Forms.ListViewItem listviewX, listviewY; 127 // 将比较对象转换为ListViewItem对象 128 listviewX = (System.Windows.Forms.ListViewItem)x; 129 listviewY = (System.Windows.Forms.ListViewItem)y; 130 string xText = listviewX.SubItems[ColumnToSort].Text; 131 string yText = listviewY.SubItems[ColumnToSort].Text; 132 133 //此时ListViewX、listviewY的属性项要已经绑定好数据, 134 //如:listviewX.SubItems[0].Tag = "10240"; 135 //如:listviewY.SubItems[0].Tag = "40960"; 136 //使用Tag主要用于数字排序,比如按文件夹的大小排序, 137 //此时Text已经不能转化为数字,因为根据需要, 138 //此时Text可能是:100KB,20.4MB这样的字符串 139 //string xText = listviewX.SubItems[ColumnToSort].Tag.ToString(); 140 //string yText = listviewY.SubItems[ColumnToSort].Tag.ToString(); 141 int xInt, yInt; 142 // 比较,如果值为IP地址,则根据IP地址的规则排序。 143 if (IsIP(xText) && IsIP(yText)) 144 { 145 compareResult = CompareIp(xText, yText); 146 } 147 else if (int.TryParse(xText, out xInt) && int.TryParse(yText, out yInt)) //是否全为数字 148 { 149 //比较数字 150 compareResult = CompareInt(xInt, yInt); 151 } 152 else 153 { 154 //比较对象 155 compareResult = ObjectCompare.Compare(xText, yText); 156 } 157 // 根据上面的比较结果返回正确的比较结果 158 if (OrderOfSort == System.Windows.Forms.SortOrder.Ascending) 159 { 160 // 因为是正序排序,所以直接返回结果 161 return compareResult; 162 } 163 else if (OrderOfSort == System.Windows.Forms.SortOrder.Descending) 164 { 165 // 如果是反序排序,所以要取负值再返回 166 return (-compareResult); 167 } 168 else 169 { 170 // 如果相等返回0 171 return 0; 172 } 173 } 174 #endregion 175 176 #region 私有方法 177 /// <summary> 178 /// 判断是否为正确的IP地址,IP范围(0.0.0.0~255.255.255) 179 /// </summary> 180 /// <param name="ip">需验证的IP地址</param> 181 /// <returns></returns> 182 private bool IsIP(string ip) 183 { 184 return Regex.Match(ip, @"^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\. 185 (25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\. 186 (25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\. 187 (25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$").Success; 188 } 189 190 /// <summary> 191 /// 比较两个IP地址的大小 192 /// </summary> 193 /// <param name="ipx">要比较的第一个对象</param> 194 /// <param name="ipy">要比较的第二个对象</param> 195 /// <returns>比较的结果.如果相等返回0,如果x大于y返回1,如果x小于y返回-1</returns> 196 private int CompareIp(string ipx, string ipy) 197 { 198 string[] ipxs = ipx.Split('.'); 199 string[] ipys = ipy.Split('.'); 200 for (int i = 0; i < 4; i++) 201 { 202 if (Convert.ToInt32(ipxs[i]) > Convert.ToInt32(ipys[i])) 203 { 204 return 1; 205 } 206 else if (Convert.ToInt32(ipxs[i]) < Convert.ToInt32(ipys[i])) 207 { 208 return -1; 209 } 210 else 211 { 212 continue; 213 } 214 } 215 return 0; 216 } 217 218 /// <summary> 219 /// 比较两个数字的大小 220 /// </summary> 221 /// <param name="ipx">要比较的第一个对象</param> 222 /// <param name="ipy">要比较的第二个对象</param> 223 /// <returns>比较的结果.如果相等返回0,如果x大于y返回1,如果x小于y返回-1</returns> 224 private int CompareInt(int x, int y) 225 { 226 if (x > y) 227 { 228 return 1; 229 } 230 else if (x < y) 231 { 232 return -1; 233 } 234 else 235 { 236 return 0; 237 } 238 } 239 #endregion 240 } 241 }
以上代码封装后无须更改,在窗体中添加一个ListView控件,在窗体的Load事件中添加如下代码:
1 private void Form1_Load(object sender, EventArgs e) 2 { 3 this.listView1.ListViewItemSorter = new Common.ListViewColumnSorter(); 4 this.listView1.ColumnClick += new ColumnClickEventHandler(Common.ListViewHelper.ListView_ColumnClick); 5 }
转载自:http://bbs.csdn.net/topics/350071962
本人根据自己需要,对代码做了少许修改(已注释掉),如下所示,如有类似需求,可以尝试使用