Pergunta

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.

Foi útil?

Solução

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top