Notice that when the Checkbox is not checked and the DataGridView is filled with random numbers, all of the column show the same data, while the original data sent to the DataGridView are all different random numbers (see bottom DataGridView). In addition, when sorting one column, all of the columns sort at the same time.
The problem is that the intended case-different column names are not interpreted as being different, because the Column.PropertyName is not case-sensitive, so all of the variants used for the name Jane are seen as the same in lower case (jane).
When the Checkbox is checked, and the DataGridView is filled with random numbers, all of the column shows the correct original data that is linked from the Data Table.
1. Create a new .NET Project (2015 or later) using Windows Forms
2. Add a Button1, Checkbox1, DataGridView1, and DataGridView2 control to Form1.
3. Paste the code below into Button1.
4. Run with and without the checkbox selected.
5. When the fix is not applied, try sorting any row in the top DGV, and you will notice that all of the columns sort at the same time.
'(Paste all code below into Button1)
'Fill a 10x10 array with random uniform numbers (0,1,...9 x 0,1,...,9)
Randomize(123456) ' set the seed for the RNG
Dim dataarray(9, 9) As Double
For i As Integer = 0 To 9
For j As Integer = 0 To 9
dataarray(i, j) = Rnd()
Next
Next
Dim fieldnames() As String = {"jane", "Jane", "jAne", "jaNe", "janE", "JAne", "jANe", "jaNE", "JANe", "JANE"}
' Create a data table and fill it with the random numbers
Dim dt As New DataTable
dt.Clear()
dt.Rows.Clear()
dt.Columns.Clear()
For j As Integer = 0 To UBound(fieldnames)
dt.Columns.Add(fieldnames(j), GetType(String))
Do While dt.Rows.Count <= UBound(fieldnames)
Dim myRow As DataRow
myRow = dt.NewRow()
dt.Rows.Add(myRow)
Loop
' Add each item to the cells in the column.
For i As Integer = 0 To UBound(fieldnames)
dt.Rows(i)(j) = dataarray(i, j)
Next i
Next j
'The code below will fix the bug by adding an increasing number of trailing blanks on the column name if the lower case version of the column name is seen multiple times.
If CheckBox1.Checked = True Then
Dim dicColNames As New Dictionary(Of String, Integer)
For i As Integer = 0 To dt.Columns.Count - 1
If dicColNames.ContainsKey(dt.Columns(i).ColumnName.ToLower) = True Then
Dim origcolname As String = dt.Columns(i).ColumnName.ToLower
For k As Integer = 0 To dicColNames(dt.Columns(i).ColumnName.ToLower)
dt.Columns(i).ColumnName &= " "
Next
dicColNames(origcolname) += 1
End If
If dicColNames.ContainsKey(dt.Columns(i).ColumnName.ToLower) = False Then
dicColNames.Add(dt.Columns(i).ColumnName.ToLower, 1)
End If
Next i
End If
'Set some properties of the DataGridView1 on the Form
DataGridView1.AutoGenerateColumns = False
DataGridView1.DataSource = dt
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
DataGridView1.Columns.Clear()
'Fill the DGV with the data from the data table
For i As Integer = 0 To dt.Columns.Count - 1
Dim Column As New DataGridViewTextBoxColumn
Column.Name = dt.Columns(i).ColumnName
Column.DataPropertyName = dt.Columns(i).ColumnName
Column.HeaderText = dt.Columns(i).ColumnName
Column.FillWeight = 70
Column.MinimumWidth = 70
DataGridView1.Columns.Add(Column)
Next i
DataGridView1.Rows(0).Cells(0).Selected = False
'Create second data table (dt2) and fill with the same random numbers sent to data table 1 (dt)
'Use column names that are simply 0,1,...,9, so that case-sensitive issues are not an issue
Dim dt2 As New DataTable
dt2.Clear()
dt2.Rows.Clear()
dt2.Columns.Clear()
For j As Integer = 0 To UBound(fieldnames)
dt2.Columns.Add(j, GetType(String))
Do While dt2.Rows.Count <= UBound(fieldnames)
Dim myRow As DataRow
myRow = dt2.NewRow()
dt2.Rows.Add(myRow)
Loop
' Add each item to the cells in the column.
For i As Integer = 0 To UBound(fieldnames)
dt2.Rows(i)(j) = dataarray(i, j)
Next i
Next j
'Set some properties of the DataGridView2 on the Form
DataGridView2.AutoGenerateColumns = False
DataGridView2.DataSource = dt2
DataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
DataGridView2.Columns.Clear()
'Fill the second DGV with the same random data
For i As Integer = 0 To dt2.Columns.Count - 1
Dim Column As New DataGridViewTextBoxColumn
Column.Name = i.ToString
Column.DataPropertyName = i.ToString
Column.HeaderText = i.ToString
Column.FillWeight = 70
Column.MinimumWidth = 70
DataGridView2.Columns.Add(Column)
Next i
DataGridView2.Rows(0).Cells(0).Selected = False