如何在用户单击列标题时启用DataGridView排序?

66 c# sorting datagridview winforms

我的表单上有一个datagridview,我填充它:

dataGridView1.DataSource = students.Select(s => new { ID = s.StudentId, RUDE = s.RUDE, Nombre = s.Name, Apellidos = s.LastNameFather + " " + s.LastNameMother, Nacido = s.DateOfBirth })
                                   .OrderBy(s => s.Apellidos)
                                   .ToList();
Run Code Online (Sandbox Code Playgroud)

现在,我使用s.Apellidos作为默认排序,但我也想允许用户在单击列标题时进行排序.

这种排序不会以任何方式修改数据,它只是一个客户端奖励,以便在用眼睛扫描屏幕时更容易搜索信息.

谢谢你的建议.

Mar*_*hal 50

将所有列(可由用户排序)SortMode属性设置为Automatic

dataGridView1.DataSource = students.Select(s => new { ID = s.StudentId, RUDE = s.RUDE, Nombre = s.Name, Apellidos = s.LastNameFather + " " + s.LastNameMother, Nacido = s.DateOfBirth })
                                   .OrderBy(s => s.Apellidos)
                                   .ToList();

    foreach(DataGridViewColumn column in dataGridView1.Columns)
    {

        column.SortMode = DataGridViewColumnSortMode.Automatic;
    }
Run Code Online (Sandbox Code Playgroud)

编辑:由于您的datagridview绑定了linq查询,因此不会对其进行排序.因此,请通过此链接说明如何创建可排序的绑定列表,然后将其作为数据源提供给datagridview.

  • 顺便说一句,你的`foreach`可能很简单:`的foreach(在dataGridView1.Columns的DataGridViewColumn列)column.SortMode = DataGridViewColumnSortMode.Automatic;` (4认同)
  • @Sergio:所以,如果我理解正确,现在你没有得到任何错误,但仍然没有列可排序. (2认同)
  • @Niraj:正确.我点击列标题,行不按自己的顺序排列. (2认同)

Tom*_*ell 26

正如Niraj建议的那样,使用SortableBindingList.我已经非常成功地使用了DataGridView.

这是我使用的更新代码的链接 - 呈现SortableBindingList - Take Two

只需将两个源文件添加到您的项目中,您就可以开展业务了.

Source位于SortableBindingList.zip中


San*_*h B 6

您的数据网格首先需要绑定到可排序列表.

创建此事件处理程序:

    void MakeColumnsSortable_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
        //Add this as an event on DataBindingComplete
        DataGridView dataGridView = sender as DataGridView;
        if (dataGridView == null)
        {
            var ex = new InvalidOperationException("This event is for a DataGridView type senders only.");
            ex.Data.Add("Sender type", sender.GetType().Name);
            throw ex;
        }

        foreach (DataGridViewColumn column in dataGridView.Columns)
            column.SortMode = DataGridViewColumnSortMode.Automatic;
    }
Run Code Online (Sandbox Code Playgroud)

并初始化每个datragrids的事件,如下所示:

        dataGridView1.DataBindingComplete += MakeColumnsSortable_DataBindingComplete;
Run Code Online (Sandbox Code Playgroud)


thi*_*zar 5

你可以像这样使用DataGridViewColoumnHeaderMouseClick事件:

Private string order = String.Empty;
private void dgvDepartment_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if (order == "d")
{
        order = "a";                
dataGridView1.DataSource = students.Select(s => new { ID = s.StudentId, RUDE = s.RUDE, Nombre = s.Name, Apellidos = s.LastNameFather + " " + s.LastNameMother, Nacido = s.DateOfBirth })   .OrderBy(s => s.Apellidos).ToList();
    }
    else
    {
        order = "d";
        dataGridView1.DataSource = students.Select(s => new { ID = s.StudentId, RUDE = s.RUDE, Nombre = s.Name, Apellidos = s.LastNameFather + " " + s.LastNameMother, Nacido = s.DateOfBirth }.OrderByDescending(s => s.Apellidos)  .ToList()
    }
}
Run Code Online (Sandbox Code Playgroud)


Vid*_*ati 5

实现此目的的另一种方法是使用“ System.Linq.Dynamic”库。您可以从Nuget获取此库。无需任何自定义实现或可排序的列表:)

using System.Linq.Dynamic;
private bool sortAscending = false;

private void dataGridView_ColumnHeaderMouseClick ( object sender, DataGridViewCellMouseEventArgs e )
{
    if ( sortAscending )
        dataGridView.DataSource = list.OrderBy ( dataGridView.Columns [ e.ColumnIndex ].DataPropertyName ).ToList ( );
    else
        dataGridView.DataSource = list.OrderBy ( dataGridView.Columns [ e.ColumnIndex ].DataPropertyName ).Reverse ( ).ToList ( );
    sortAscending = !sortAscending;
}
Run Code Online (Sandbox Code Playgroud)

  • 效果就像一个魅力,不敢相信还没有人给你积极的反馈 (2认同)
  • 对于“else”情况使用“OrderByDescending”会更好。 (2认同)
  • 效果很好!不要忘记添加 ```dataGridView.ColumnHeaderMouseClick += dataGridView_ColumnHeaderMouseClick;``` 并为 BindingList 实现此功能,每次数据进入时都会更新...您必须修改代码... ```dataGridView.DataSource = new BindingList<Data>(dataList.OrderBy(dataGridView.Columns[e.ColumnIndex].DataPropertyName).ToList());``` (2认同)

001*_*014 5

您无需创建绑定数据源。如果您想对所有列进行排序,这是我的一个更通用的解决方案;

private int _previousIndex;
private bool _sortDirection;

private void gridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.ColumnIndex == _previousIndex)
        _sortDirection ^= true; // toggle direction

    gridView.DataSource = SortData(
        (List<MainGridViewModel>)gridReview.DataSource, gridReview.Columns[e.ColumnIndex].Name, _sortDirection);

    _previousIndex = e.ColumnIndex;
}

public List<MainGridViewModel> SortData(List<MainGridViewModel> list, string column, bool ascending)
{
    return ascending ? 
        list.OrderBy(_ => _.GetType().GetProperty(column).GetValue(_)).ToList() :
        list.OrderByDescending(_ => _.GetType().GetProperty(column).GetValue(_)).ToList();
}
Run Code Online (Sandbox Code Playgroud)

确保您为事件订阅了数据网格ColumnHeaderMouseClick。当用户单击列时,它将按降序排序。如果再次单击相同的列标题,则将按升序应用排序。