Home > front end >  Change ComboBox Text from its own SelectedIndexChanged event handler
Change ComboBox Text from its own SelectedIndexChanged event handler

Time:11-01

I'm trying to create a ComboBox that shows the current status, and has its options change the program's status.

Although it works, I cannot get it to show the current status.

Whenever one of the ComboBox events raise, when I set the ComboBox.Text property to anything, it is simply ignored and whatever I selected is set. I can change the SelectedIndex to -1 and it empties the Edit Control, but even afterwards, I cannot change comboboxthe Text, as if that event is fired before anything else.

Adding a Command button does allow me to change the text of the ComboBox just fine though.

Here's my test application:

Create a Button, bComboAdd, a Label, lTest and a ComboBox: cbSelect.
Add two items to cbSelect and set the Text to something different.
In my test, I set the items to "Set to ," and "Set to ;".

Use the following code:

Private Sub bComboAdd_Click(sender As Object, e As EventArgs) Handles bComboAdd.Click
    me.cbSelect.Text = "Testing"
    me.lTest.Text = "Testing"
End Sub

Private Sub cbSelect_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbSelect.SelectedIndexChanged
    Select Case Me.cbSelect.SelectedIndex
        Case 0
            Me.cbSelect.Text = "Mode: ,"
            me.lTest.Text = "Mode: ,"
        Case 1
            Me.cbSelect.Text = "Mode: ;"
            me.lTest.Text = "Mode: ;"
    End Select
End Sub

enter image description here

cbSelect.Text = [...] is ignored, while the lTest.Text works just fine.
I click the ComboBox, set it to "Set to ;" and the text changes to "Set to ;" while the label changes to "mode: ;"

I also tried this, same result:

Private Sub cbSelect_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbSelect.SelectedIndexChanged

    Select Case Me.cbSelect.SelectedItem
        Case "Set to ,"
            Me.cbSelect.Text = "Mode: ,"
            Me.lTest.Text = "Mode: ,"
        Case "Set to ;"
            Me.cbSelect.Text = "Mode: ;"
            Me.lTest.Text = "Mode: ;"
    End Select
End Sub

Now, if I add the status texts as selectable text in the list, even at runtime, it works. But if I remove them again at runtime too, it doesn't work. So it seems there is some kind of validation going on, but only when I set the text from the control itself.

How can I get the Text of the ComboBox to change as expected?

CodePudding user response:

When the SelectedIndexChanged event of a ComboBox is raised, the underlying code also sends a message to the ComboBox to update its text (here are the notes about it).

This means that when you set the Text of the ComboBox, it's updated - right after the event handler exits - with the text of the SelectedItem ([ComboBox].GetItemText(Items(SelectedIndex))).

By deferring the execution of the code that sets the Text property, using BeginInvoke(), you act after the text of the ComboBox has been updated, so you override the previously mentioned procedure:

Private Sub cbSelect_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbSelect.SelectedIndexChanged
    If cbSelect.SelectedIndex < 0 Then Return
    Dim cboText = string.Empty
    Select Case cbSelect.GetItemText(cbSelect.SelectedItem)
        Case "Something"
            cboText = "Other"
        ' [...] 
    End Select
    BeginInvoke(new Action(Sub() cbSelect.Text = cboText))
End Sub

Unsolicited suggestion:
You could use a Dictionary(Of String String) to store the values you want to set and use the SelectedItems text value as the Key of the Dictionary to retrieve the corresponding text, so you just need to use [Dictionary].ContainsKey() to validate the selected text, then get the matching value used to change the Text of the ComboBox.

  • Related