DataGridView Sort does not work

13,867

Solution 1

If I remember correctly you can put a binding source between you collection and the datagridview and the binding source will provide a bunch of functionality. I think it allows you to sort as well. This is all just off the top of my head as I can't test it right now.

Solution 2

The key thing here is that the DataGridView isn't responsible for sorting; the underlying data-source (i.e. .DataSource of the DataSource) is.

you could implement something like this SortableBindingList (for Windows.Forms) http://www.martinwilley.com/net/code/forms/sortablebindinglist.html

Share:
13,867
Bodger
Author by

Bodger

Updated on July 02, 2022

Comments

  • Bodger
    Bodger almost 2 years

    Visual Studio 2010 VB.NET

    I have a DataGridView.DataSource set to a Collection of custom objects. The columns use read only properties from the custom object for display, this dialog is for display only. The properties all return String objects. I set the columns all but 2 of them to sortmode automatic (the ones that are not set is a button or a checkbox). Yet it does not sort. I have googled around and most people use sql or binding sources but I am using a trivial vb collection. Some say I should implement IComparable but isn't String already IComparable?

    Any help would be appreciated?

    Thanx

    Bodger

    Per a request here are some code snippets.

    This method defines the columns in detail from columns I designed in the designer.

    The column names are called pSelected or pCustomer and corresponds with a property by the same name that the column definition ties to.

    
    Protected Sub UpdateDGVUS()
            If Not USColumnsInitted Then
                USColumnsInitted = True
    
                dgvUS.AutoGenerateColumns = False
                dgvUS.Columns.Clear()
    
                Dim iIdx As Integer
    
                iIdx = 0
    
                dgvUS.Columns.Insert(iIdx, Me.pSelected)
                dgvUS.Columns("pSelected").DisplayIndex = iIdx
                dgvUS.Columns("pSelected").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pCustomer)
                dgvUS.Columns("pCustomer").DisplayIndex = iIdx
                dgvUS.Columns("pCustomer").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pDetails)
                dgvUS.Columns("pDetails").DisplayIndex = iIdx
                dgvUS.Columns("pDetails").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pSelectCustomerInvoice)
                dgvUS.Columns("pSelectCustomerInvoice").DisplayIndex = iIdx
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pDate)
                dgvUS.Columns("pDate").DisplayIndex = iIdx
                dgvUS.Columns("pDate").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pAmount)
                dgvUS.Columns("pAmount").DisplayIndex = iIdx
                dgvUS.Columns("pAmount").DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
                dgvUS.Columns("pAmount").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pName)
                dgvUS.Columns("pName").DisplayIndex = iIdx
                dgvUS.Columns("pName").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pPayment)
                dgvUS.Columns("pPayment").DisplayIndex = iIdx
                dgvUS.Columns("pPayment").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pCompany)
                dgvUS.Columns("pCompany").DisplayIndex = iIdx
                dgvUS.Columns("pCompany").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pType)
                dgvUS.Columns("pType").DisplayIndex = iIdx
                dgvUS.Columns("pType").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dgvUS.Columns.Insert(iIdx, Me.pDescription)
                dgvUS.Columns("pDescription").DisplayIndex = iIdx
                dgvUS.Columns("pDescription").SortMode = DataGridViewColumnSortMode.Automatic
                iIdx = iIdx + 1
    
                dataUpdatedUS()
            End If
        End Sub
    

    This is a snippet of the custom object that is in the collection

    
    Public Class ItemXact01
        Public Property FirstName As String
        Public Property LastName As String
        Public Property Company As String
        Public Property Type As String
        Public Property Description As String
        Public Property RefNumber As String
        Public Property DownloadID As String
        Public Property Selected As Boolean
        Public Property RequestID As Integer
    
        ...
    
        Public ReadOnly Property pCompany As String
            Get
                pCompany = Company
            End Get
        End Property
    
        Public ReadOnly Property pType As String
            Get
                pType = Type
            End Get
        End Property
    
        Public ReadOnly Property pDescription As String
            Get
                pDescription = Description
            End Get
        End Property
    
        Public ReadOnly Property pSelected As Boolean
            Get
                pSelected = Selected
            End Get
        End Property
    
    

    ...

    The data is put into place with this code

    
        Private Sub dataUpdateDGV(ByRef dgv As DataGridView, ByRef myCollection As Collection)
            myMain.Log("dataUpdatedDGV: 001 :" & dgv.RowCount & ":" & myCollection.Count & ":")
    
    ' for some reason the not equal to does not show in the next line
    
            If dgv.RowCount  myCollection.Count Then
                myMain.Log("dataUpdatedDGV: 002")
    
                dgv.DataSource = Nothing
                If myCollection.Count > 0 Then
                    myMain.Log("dataUpdatedDGV: 003")
    
                    dgv.DataSource = myCollection
                End If
            End If
    
            myMain.Log("dataUpdatedDGV: 004")
    
            dgv.Invalidate()
            dgv.Update()
            dgv.Refresh()
    
            myMain.Log("dataUpdatedDGV: OUT")
        End Sub
    
  • Bodger
    Bodger over 13 years
    Thank you for your response, but I don't need it custom sorted, I just want it sorted by the column selected. Nothing happens when I click on the column header.
  • Bodger
    Bodger over 13 years
    I found a SortableBindingList class out in the ether and it works.
  • The Dag
    The Dag about 11 years
    You're right, but it must be said it is a disastrous design. How a grid is sorted is clearly a presentation matter and should be handled by the control. And frankly it's difficult to see why it would be hard to do, so long as the bound values in a column are the same type (usually the case) and implement IComparable (as all the basic datatypes do). One side-effect of this winforms approach is that you can't bind a list to multiple views, because the datasource tracks order and selected item and so on. Picture a view with lots of amounts and a dropdown list of currencies associated with each.
  • Nick Wallace
    Nick Wallace almost 11 years
    The sorting applied to a particular grid is in the DataGridView. The method for actual sorting is in the DataSource.