封裝 ListViewHelper 靜態類別與 ListViewColumnSorter 實作 IComparer,支援點擊欄標切換升冪/降冪、數值/IP 地址/字串三種比較模式。
public class ListViewHelper
{
public static void ListView_ColumnClick(object sender, ColumnClickEventArgs e)
{
ListView lv = sender as ListView;
var sorter = lv.ListViewItemSorter as ListViewColumnSorter;
if (e.Column == sorter.SortColumn)
sorter.Order = sorter.Order == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
else
{
sorter.SortColumn = e.Column;
sorter.Order = SortOrder.Ascending;
}
lv.Sort();
}
}
public class ListViewColumnSorter : IComparer
{
private int ColumnToSort;
private SortOrder OrderOfSort;
private CaseInsensitiveComparer ObjectCompare = new CaseInsensitiveComparer();
public int Compare(object x, object y)
{
ListViewItem lx = (ListViewItem)x, ly = (ListViewItem)y;
string tx = lx.SubItems[ColumnToSort].Text, ty = ly.SubItems[ColumnToSort].Text;
int cmp;
if (IsIP(tx) && IsIP(ty)) cmp = CompareIp(tx, ty);
else if (int.TryParse(tx, out int xi) && int.TryParse(ty, out int yi)) cmp = xi.CompareTo(yi);
else cmp = ObjectCompare.Compare(tx, ty);
return OrderOfSort == SortOrder.Ascending ? cmp : (OrderOfSort == SortOrder.Descending ? -cmp : 0);
}
public bool IsIP(string ip) => Regex.IsMatch(ip, @"^(25[0-5]|2[0-4]\d|[01]?\d?\d)(\.(25[0-5]|2[0-4]\d|[01]?\d?\d)){3}$");
private int CompareIp(string a, string b) { var aa=a.Split('.'); var bb=b.Split('.'); for(int i=0;i<4;i++){ int ca=int.Parse(aa[i]), cb=int.Parse(bb[i]); if(ca!=cb) return ca.CompareTo(cb);} return 0; }
public int SortColumn { get => ColumnToSort; set => ColumnToSort = value; }
public SortOrder Order { get => OrderOfSort; set => OrderOfSort = value; }
}
private void Form1_Load(object sender, EventArgs e)
{
listView1.ListViewItemSorter = new ListViewColumnSorter();
listView1.ColumnClick += ListViewHelper.ListView_ColumnClick;
}