When a DataGridView is databound it is not possible to use its sorting and it is necessary to sort source data. The 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 one will contain a leading letters (or empty string). The second will contain only a number contained in the string. We will sort by Scol1, Scol2
.
Now we set all comumns to Programatic
mode (DataGridViewColumnSortMode Enumeration)
For Each column As DataGridViewColumn In dgvBills.Columns
column.SortMode = DataGridViewColumnSortMode.Programmatic
Next
And custom sorting is achieved in a handler of ColumnHeaderMouseClick
(DataGridView.Sort Method (IComparer)). We will use sorting of the underlying view instead of the Grid sorting.
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 ...
is possible to set columns which are sorted differntly. Other columns are sorted as the Grid sorts them by default or it is possible to create another custom sorting.
Note: I have fully working example but I hope that fragments are good enough.