I have a strange problem with case when using a datagridviewcomboboxcolumn
within an unbound datagridview. The column is initially populated with valid values, some of which are all uppercase and some mixed case, but always unique. For example, "AB","AC",AiDA","AltCurr","BE", etc.
When selecting any of the uppercase items, everything works fine. If, however, I select one of the mixed-case items from the drop-down in the cell, a "cell contains invalid data" DataError event is issued, and the cell selects "AB" (i.e. unable to find selection so it defaults to the first entry).
If I change all the list items to uppercase, the problem does not occur (but this is not an option in reality!).
I've read plenty of comments about case sensitivity in BOUND datagridview combo columns, with the solution being to alter the case sensitivity options on the underlying datatable, but nothing that would overcome my specific unbound issue.
Has anybody else come across this, and if so, how did you fix it?
EDIT: Code samples as requested...
The Datagridviewcomboboxcolumn is already created in the designer (col #2). It is populated as follows from a collection of objects:
m_subjectList = new SubjectList
for each sj as Subject in m_subjectlist
ctype(dgv.columns(2),datagridviewcomboboxcolumn).items.add(sj.SubjectCode) 'a string value
next
Rows are manually added from an underlying datatable:
for each dr as datarow in ds.tables("Mappings").rows
dim r as integer = dgv.rows.add
dgv.rows(r).cells(2).value = dr("SubjectCode") 'varchar(10)
next
Everything works fine up to this point - the DGV displayes correctly with the values in the cell combo's all correct. There's no more code required.
Now, if I click the drop-down on any of these rows to change the subject, it all works fine UNLESS I choose the 'AiDA' or 'AltCurr' items (i.e. ones with mixed case). The dataerror context is Formatting | Display.
If I choose any of the list items that are all uppercase, the issue does not arise. It seems to me that the combo cell is not finding the mixed case items in its objectcollection - there's a difference in the case sensitivity of the underlying combo's object collection and the case sensitivity of whatever the DGV uses to check the validity within the collection.
I've managed to answer my own question.
It seems that my theory about the case-sensitivity differences within the comboboxcolumn's objectcollection is (at least in part) correct. Instead of adding string values to the Items collection, use a custom object instead which contains the original and uppercase versions of the string.
This now works:
Public Class ComboCellItem
Private m_Value As String
Private m_Description As String
Public ReadOnly Property Value() As String
Get
Return m_Value
End Get
End Property
Public ReadOnly Property Description() As String
Get
Return m_Description
End Get
End Property
Public Sub New(ByVal Value As String, ByVal Description As String)
m_Value = Value
m_Description = Description
End Sub
End Class
Now create all the comboboxcolumn items using the ComboCellItem object. Note that both properties of the ComboCellItem object are identical EXCEPT that one is stored UPPERCASE:
m_SubjectList = New SubjectList(m_dbc)
For Each sj As Subject In m_SubjectList
Dim r As Integer = .Rows.Add
CType(dgvMap.Columns(2), DataGridViewComboBoxColumn).Items.Add _
(New ComboCellItem(sj.SubjectCode.ToUpper, sj.SubjectCode))
Next
Set the Displaymember of the combocolumn to the original (non-uppercase) value and the Valuemember to the uppercase element:
CType(dgvMap.Columns(2), DataGridViewComboBoxColumn).DisplayMember = "Description"
CType(dgvMap.Columns(2), DataGridViewComboBoxColumn).ValueMember = "Value"
Finally, when creating and populating the rows, make sure you set the combocell value to the UPPERCASE value of the underlying data:
For Each dr As DataRow In ds.tables("Mappings").Rows
Dim r As Integer = dgvMap.Rows.Add
dgvMap.Rows(r).Cells(2).Value = dr("SubjectCode").ToString.ToUpper
Next
Now, when you select a mixed-case item from the drop-down, everything works as expected. It seems that the DatagridviewComboboxColumn's internal workings mean that you simply can't use it unbound with a list of simple string values unless they are all uppercase. There are obvious differences in how it handles the case sensitivity of what it displays compared to how it searches its underlying collection of items.
That's wasted almost a day of my productive time, but at least I'll know next time.
How frustrating!
Derek