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

C# 強化 ListView 控制項:自訂排序與自動欄寬調整

     編輯:關於C#

功能一:點擊欄標自訂排序

核心實作:IComparer 介面


class ListViewColumnSorter : IComparer
{
    private readonly int _columnIndex;
    private readonly SortOrder _order;

    public ListViewColumnSorter(int columnIndex, SortOrder order)
    {
        _columnIndex = columnIndex;
        _order = order;
    }

    public int Compare(object x, object y)
    {
        ListViewItem itemX = (ListViewItem)x;
        ListViewItem itemY = (ListViewItem)y;
        string textX = itemX.SubItems[_columnIndex].Text;
        string textY = itemY.SubItems[_columnIndex].Text;

        int result = String.Compare(textX, textY, StringComparison.CurrentCulture);
        return _order == SortOrder.Descending ? -result : result;
    }
}

事件綁定


private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
    // 切換排序順序 (Tag 保存目前順序)
    SortOrder newOrder = SortOrder.Ascending;
    if (listView1.Columns[e.Column].Tag is SortOrder currentOrder)
    {
        newOrder = currentOrder == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
    }
    listView1.Columns[e.Column].Tag = newOrder;

    // 重設其他欄 Tag (可選:單欄排序模式)
    foreach (ColumnHeader col in listView1.Columns)
        if (col.Index != e.Column) col.Tag = null;

    listView1.ListViewItemSorter = new ListViewColumnSorter(e.Column, newOrder);
    listView1.Sort();
}

功能二:最後一欄自動填滿剩餘寬度

調整邏輯


private void AdjustLastColumnWidth()
{
    if (listView1.Columns.Count == 0) return;

    // 暫時移除事件避免遞迴觸發
    listView1.ColumnWidthChanged -= ListView1_ColumnWidthChanged;

    int totalWidth = listView1.ClientSize.Width;
    int usedWidth = 0;
    for (int i = 0; i < listView1.Columns.Count - 1; i++)
        usedWidth += listView1.Columns[i].Width;

    int lastWidth = Math.Max(50, totalWidth - usedWidth - SystemInformation.VerticalScrollBarWidth);
    listView1.Columns[listView1.Columns.Count - 1].Width = lastWidth;

    listView1.ColumnWidthChanged += ListView1_ColumnWidthChanged;
}

private void ListView1_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
    => AdjustLastColumnWidth();

private void ListView1_SizeChanged(object sender, EventArgs e)
    => AdjustLastColumnWidth();

private void Form1_Shown(object sender, EventArgs e)
    => AdjustLastColumnWidth(); // 首次顯示調整

進階強化建議

功能實作要點
數值/日期排序IComparer 中嘗試 double.TryParse/DateTime.TryParse,失敗回退字串比較
多欄排序Shift+Click 累加排序鍵,IComparer 依優先序比較多欄
排序指示器圖示OwnerDraw 模式繪製 ▲/▼ 於 ColumnHeader
虛擬模式大量資料 (>1萬筆) 設定 VirtualMode=true,配合 RetrieveVirtualItem 事件
雙緩衝減少閃爍反射設定 listView1.GetType().GetProperty("DoubleBuffered", BindingFlags.NonPublic|BindingFlags.Instance).SetValue(listView1, true);

完整程式碼結構


public partial class EnhancedListViewForm : Form
{
    public EnhancedListViewForm()
    {
        InitializeComponent();
        listView1.View = View.Details;
        listView1.FullRowSelect = true;
        listView1.ColumnClick += ListView1_ColumnClick;
        listView1.ColumnWidthChanged += ListView1_ColumnWidthChanged;
        listView1.SizeChanged += ListView1_SizeChanged;
        this.Shown += Form1_Shown;
    }
    // ... 上述所有事件處理方法
}

透過 IComparer 與事件機制,ListView 即可具備專業級排序與自適應欄寬能力,大幅提升使用者體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved