jbryan10 jbryan10 - 2 months ago 11x
Vb.net Question

Visual Studio ComboBox won't cycle through items with up/down arrows once users types

I have a userform with a dropdown combobox that is filled with items when the form is opened. If the box has focus, the up/down arrow keys will cycle through the items (as it should), or the user can select from the drop down list and still be able to use the up/down arrows from there. If the user starts typing, the box is set to append from the list items, but that disables the up/down arrow keys from cycling through ALL the items. At that point, it only cycles through the items that start with whatever the user typed. I would like it to erase the typed data and cycle through all the combobox items (starting at the index was whatever was appended) just like it does in the VBA version.

Even if the user types something, then selects a completely different item from the dropdown, the next time up/down keys are pressed, it only goes back to whatever was typed.

I attempted to handle this in the arrow up/down keydown (or keyup) event as follows:

Private Sub SeriesBox_KeyDown(sender As Object, e As KeyEventArgs) Handles SeriesBox.KeyDown

Dim CurIndex As Integer = SeriesBox.FindStringExact(SeriesBox.Text)
Select Case e.KeyCode

Case Keys.Down

SeriesBox.Text = String.Empty
SeriesBox.SelectedIndex = CurIndex + 1

Case Keys.Up

SeriesBox.Text = String.Empty
SeriesBox.SelectedIndex = CurIndex - 1

End Select

End Sub

The arrow keys don't actually enter this sub, so I tried adding:

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keydata As Keys) As Boolean

If keydata = Keys.Right Or keydata = Keys.Left Or keydata = Keys.Up Or keydata = Keys.Down Then
OnKeyDown(New KeyEventArgs(keydata))
ProcessCmdKey = True
ProcessCmdKey = MyBase.ProcessCmdKey(msg, keydata)
End If

End Function

But this didn't seem to make a difference. Is there something I am missing?


This may work:

First set you combobox's AutoCompleteMode and AutoCompleteSouce to None

Then paste this to your code:

 Private Sub SeriesBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles SeriesBox.TextChanged
    For Each it As String In SeriesBox.Items
        If Not SeriesBox.Text = it Then
            If it.Contains(SeriesBox.Text) Then
                Dim length As Integer = SeriesBox.Text.Length
                SeriesBox.Text = ""
                SeriesBox.Text = it
                SeriesBox.Select(length, SeriesBox.Text.Length - length)
                SeriesBox.SelectedItem = SeriesBox.Text
            End If
        End If
End Sub