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

本人根据自己需要,对代码做了少许修改(已注释掉),如下所示,如有类似需求,可以尝试使用

posted @ 2014-11-20 18:06  天琊蓝  阅读(1736)  评论(0编辑  收藏  举报