How do I implement automatic sorting of DataGridView?

前端 未结 3 2111
一个人的身影
一个人的身影 2020-11-27 19:53

I am programmatically adding columns to a DataGridView and then binding to a list. By default, the SortMode of the columns are Automatic. But when I run my app, clicking o

相关标签:
3条回答
  • 2020-11-27 20:11

    I think I found the answer. My datasource implements IList<T>. Apparently it need to implement IBindingList<T>. Unfortunately, I'm not able to test this.

    0 讨论(0)
  • 2020-11-27 20:15

    We use BindingListView to bind List<T>s to DataGridViews, and it's worked beautifully for us.

    Here is a very simple example of creating a view of a list of objects (in C#):

    List<Customer> customers = GetCustomers();
    BindingListView<Customer> view = new BindingListView<Customer>(customers);
    dataGridView1.DataSource = view;
    

    Check out https://stackoverflow.com/a/17952576/116891 for a lot more details about DGV sorting and databinding.

    If you don't want to add something that heavy, you can try this implementation of a SortableBindingList<T> (with updates).

    Both give you sorting right out of the box, and BindingListView is even faster than DataViews, according to their benchmarks.

    0 讨论(0)
  • 2020-11-27 20:22

    Best solution I've found:

    EDIT: Since posting I found this implementation of SortableBindingList(Of T) to be the best solution, with the exception that I modified line 52 to be IEnumerable rather than ICollection, since the constructor is casting anyway and it works.

    Alternatively, the solution below needs no custom class:

    The DataGridView may be sorted without implementing a custom class. Note that my code is in VB.NET, but it should translate. The data must first be added to the grid.Rows:

    For Each item In dataList
        grid.Rows.Add(item.Id, item.Name, item.DateProperty)
    Next
    

    Then implement these event handlers. The second one is to ensure that date sorting works. You only need it if your grid will have a sortable date column:

    Private Sub grid_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles grid.ColumnHeaderMouseClick
        Dim col = grid.Columns(e.ColumnIndex)
        Dim dir As System.ComponentModel.ListSortDirection
    
        Select Case col.HeaderCell.SortGlyphDirection
            Case SortOrder.None, SortOrder.Ascending
                dir = System.ComponentModel.ListSortDirection.Ascending
            Case Else
                dir = System.ComponentModel.ListSortDirection.Descending
        End Select
    
        grid.Sort(col, dir)
    End Sub
    
    Private Sub grid_SortCompare(ByVal sender As Object, ByVal e As DataGridViewSortCompareEventArgs) Handles grid.SortCompare
        'This event occurs only when the DataSource property is not set and the VirtualMode property value is false.
    
        If e.Column.Name = "DateProperty" Then
            e.SortResult = Date.Compare(CType(e.CellValue1, Date), CType(e.CellValue2, Date))
    
            e.Handled = True
        End If
    
    End Sub
    

    An important thing to note is that only the properties you add to the row are part of the resulting object, since there is no binding. In order to maintain your entire object, you will need to add columns for every property, setting the columns Visible = False for any that should not be displayed.

    0 讨论(0)
提交回复
热议问题