When a DataGridView is a database binding, you cannot sort it, and you need to sort the original data. Sorting is a bit complicated, so I need two helper columns.
dgvBills.AutoGenerateColumns = False tbl.Columns.Add(New DataColumn("Scol1", GetType(String))) tbl.Columns.Add(New DataColumn("Scol2", GetType(Integer)))
The first will contain leading letters (or an empty string). The second will only contain the number contained in the string. Scol1, Scol2
.
Now we set all the columns to Programatic
mode ( DataGridViewColumnSortMode Enumeration )
For Each column As DataGridViewColumn In dgvBills.Columns column.SortMode = DataGridViewColumnSortMode.Programmatic Next
And custom sorting is achieved in the ColumnHeaderMouseClick
handler ( DataGridView.Sort (IComparer) method ). We will use the main view sort instead of the Grid sort.
Private Sub dgvBills_ColumnHeaderMouseClick(sender As Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgvBills.ColumnHeaderMouseClick Dim newColumn As DataGridViewColumn = dgvBills.Columns(e.ColumnIndex) Dim direction As ListSortDirection Dim Modifier As String = "" If newColumn.HeaderCell.SortGlyphDirection = SortOrder.Ascending Then direction = ListSortDirection.Descending Modifier = " desc" Else direction = ListSortDirection.Ascending End If Dim View As DataView = dgvBills.DataSource If {"JobNumber", "JobNumber1"}.Contains(dgvBills.Columns(e.ColumnIndex).Name) Then View.Table.Columns("Scol2").Expression = String.Format("Convert(iif (substring({0},1,2) like '*-',substring({0},3,len({0})-1),{0}), 'System.Int32')", dgvBills.Columns(e.ColumnIndex).Name) View.Table.Columns("Scol1").Expression = String.Format("iif (substring({0},1,2) like '*-',substring({0},1,2),'')", dgvBills.Columns(e.ColumnIndex).Name) View.Sort = String.Format("Scol1 {0},Scol2 {0}", Modifier) Else dgvBills.Sort(newColumn, direction) End If If direction = ListSortDirection.Ascending Then newColumn.HeaderCell.SortGlyphDirection = SortOrder.Ascending Else newColumn.HeaderCell.SortGlyphDirection = SortOrder.Descending End If End Sub
In {"JobNumber", "JobNumber1"}.Contains ...
you can set columns that are sorted differently. Other columns are sorted by default Grid type, or you can create another custom sort.
Note. I have a fully working example, but I hope the snippets are good enough.