Skip to content

C# WinForm DataGridView 点击标题排序功能

代码中使用 DataGridView + BindingSource 控件显示数据。DataSource 为自定义实体的 List

csharp
// 绑定属性表格
srcField.DataSource = currentColumns;
srcField.ResetBindings(true);

发现默认的排序没有作用 (默认列的 SortModeAutomatic),需要自动手动写代码来实现排序。排序代码如下。

注意

需要注意的是绑定的列表在排序后已经变成了一个新的实体,需要重新绑定到 BindingSource,否则 DataGridView 中的数据不会刷新。
另外需要在绑定后再设置标题的状态,否则状态会被重置为 None

csharp
private void grvField_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    //取得点击列的索引
    int nColumnIndex = e.ColumnIndex;
    if (!(grvField.Columns[nColumnIndex].SortMode == DataGridViewColumnSortMode.Programmatic))
    {
        return;
    }
    switch (grvField.Columns[nColumnIndex].HeaderCell.SortGlyphDirection)
    {
        case SortOrder.None:
            //在这里加入排序的逻辑
            currentColumns = currentColumns.OrderBy(column => typeof(ColumnModel)
                .GetProperty(grvField.Columns[nColumnIndex].DataPropertyName).GetValue(column)).ToList();
            srcField.DataSource = currentColumns;
            srcField.ResetBindings(false);
            //设置列标题的状态 
            grvField.Columns[nColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
            break;
        case SortOrder.Ascending:
            //在这里加入排序的逻辑
            currentColumns = currentColumns.OrderByDescending(column => typeof(ColumnModel)
                .GetProperty(grvField.Columns[nColumnIndex].DataPropertyName).GetValue(column)).ToList();
            srcField.DataSource = currentColumns;
            srcField.ResetBindings(false);
            //设置列标题的状态 
            grvField.Columns[nColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.Descending;
            break;
        default:
            currentColumns = currentColumns.OrderBy(column => typeof(ColumnModel)
                .GetProperty(grvField.Columns[nColumnIndex].DataPropertyName).GetValue(column)).ToList();
            srcField.DataSource = currentColumns;
            srcField.ResetBindings(false);
            grvField.Columns[nColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
            break;
    }
}

排序通过使用 linqOrderBy 方法实现。

OrderBy 代理方法中根据点击列的 DataPropertyName 属性,通过反射获取 model 中该列的值。