DataGridView Sort does not work
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
Bodger
Updated on July 02, 2022Comments
-
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 over 13 yearsThank 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 over 13 yearsI found a SortableBindingList class out in the ether and it works.
-
The Dag about 11 yearsYou'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 almost 11 yearsThe sorting applied to a particular grid is in the DataGridView. The method for actual sorting is in the DataSource.