首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# ListView 欄位標題點擊自動排序完整實作

     編輯:關於C語言

功能特色

  • 點擊欄位標題切換升冪/降冪排序
  • 支援數字、IP 位址、字串三種資料型別智慧排序
  • 可重複使用的輔助類別設計
  • 零修改整合現有 ListView

核心程式碼:ListViewHelper.cs


using System;
using System.Collections;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace Common
{
    /// ListView 排序輔助類別
    public class ListViewHelper
    {
        /// 掛載到 ListView 的 ColumnClick 事件
        public static void ListView_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            ListView lv = sender as ListView;
            var sorter = lv.ListViewItemSorter as ListViewColumnSorter;
            
            if (sorter == null) return; // 未初始化排序器
            
            // 同一欄位:切換升/降冪
            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(); // 觸發排序
        }
    }

    /// 實作 IComparer 的欄位排序器
    public class ListViewColumnSorter : IComparer
    {
        private int columnToSort = 0;
        private SortOrder orderOfSort = SortOrder.None;
        private CaseInsensitiveComparer objectCompare = new CaseInsensitiveComparer();

        public int SortColumn { get => columnToSort; set => columnToSort = value; }
        public SortOrder Order { get => orderOfSort; set => orderOfSort = value; }

        public int Compare(object x, object y)
        {
            ListViewItem itemX = x as ListViewItem;
            ListViewItem itemY = y as ListViewItem;
            
            string textX = itemX.SubItems[columnToSort].Text;
            string textY = itemY.SubItems[columnToSort].Text;
            
            int compareResult;
            
            // 1. IP 位址排序
            if (IsIP(textX) && IsIP(textY))
            {
                compareResult = CompareIP(textX, textY);
            }
            // 2. 數字排序
            else if (int.TryParse(textX, out int numX) && int.TryParse(textY, out int numY))
            {
                compareResult = CompareInt(numX, numY);
            }
            // 3. 字串排序 (不區分大小寫)
            else
            {
                compareResult = objectCompare.Compare(textX, textY);
            }
            
            // 依排序方向調整結果
            if (orderOfSort == SortOrder.Ascending) return compareResult;
            if (orderOfSort == SortOrder.Descending) return -compareResult;
            return 0;
        }

        // IP 格式驗證 (0.0.0.0 ~ 255.255.255.255)
        private bool IsIP(string ip)
        {
            return 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 CompareInt(int x, int y) => x.CompareTo(y);

        private int CompareIP(string ipX, string ipY)
        {
            var partsX = ipX.Split('.');
            var partsY = ipY.Split('.');
            
            for (int i = 0; i < 4; i++)
            {
                int cmp = int.Parse(partsX[i]).CompareTo(int.Parse(partsY[i]));
                if (cmp != 0) return cmp;
            }
            return 0;
        }
    }
}

使用方式:在 Form_Load 中啟用


private void Form1_Load(object sender, EventArgs e)
{
    // 1. 指定排序器
    this.listView1.ListViewItemSorter = new Common.ListViewColumnSorter();
    
    // 2. 掛載欄位點擊事件
    this.listView1.ColumnClick += Common.ListViewHelper.ListView_ColumnClick;
}

ListView 設計時屬性建議

  • View = View.Details (詳細檢視模式)
  • FullRowSelect = true (整列選取)
  • GridLines = true (顯示分隔線)
  • Columns 預先加入所有欄位

擴充建議

需求實作方向
日期時間排序加入 DateTime.TryParse 判斷邏輯
浮點數排序加入 double.TryParse
自訂排序規則暴露 Func<string, string, int> 委派屬性
排序指示器圖示OwnerDraw 模式繪製升/降冪箭頭
多欄位排序Shift+點擊支援次要排序鍵

原理說明

  1. ListView.Sort() 內部呼叫 ListViewItemSorter.Compare() 進行比較
  2. IComparer.Compare 回傳:< 0 (x 0 (x>y)
  3. IP 排序採用逐段數值比較,避免字串比較導致 "192.168.1.10" < "192.168.1.2" 的錯誤
  4. CaseInsensitiveComparer 提供不區分大小寫的字串比較
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved