I found some code on CodeProject for autocompleting text typed into a combo box. It worked okay but I need a much cleaner implementation. So I modified the code I found and made it quite a bit more user friendly. I still have one problem though. When I type too fast, I will end up jumping ahead of the windows messages.
See normally the order is like this:
GetText
FindString
SetText
SetSelectionStart
SetSelectionLength
but when I type too fast I get extra keyup/keydown messages in there. For instance, if I get another key press between SetText and SetSelectionStart then the new character being added will be added to the end of the string instead of the start of the selection area. Its very annoying to have to type slow just so your autocomplete feature will work.
I need a way to set Text, Selection Start and Selection Length all at once or I need a way to hold (not ignore) all key messages until I'm sure all my messages have been processed.
Below is the code I am using.
Public Sub AutoCompleteCombo_KeyUp(By
Val cbo As ComboBox, ByVal PreserveCase As Boolean, ByVal e As KeyEventArgs)
Dim sTypedText As String
Dim iFoundIndex As Integer
Dim oFoundItem As Object
Dim sFoundText As String
Dim sAppendText As String
'Allow select keys without Autocompleting
Select Case e.KeyCode
Case Keys.Back, Keys.Left, Keys.Right, Keys.Up, _
Keys.Delete, Keys.Down, Keys.Home, Keys.End, _
Keys.ShiftKey, Keys.ControlKey, Keys.Tab
Return
Case Keys.Escape
cbo.SelectedText = ""
Return
End Select
'Get the Typed Text and Find it in the list
sTypedText = cbo.Text
iFoundIndex = cbo.FindString(sTypedText)
'If we found the Typed Text in the list then Autocomplete
If iFoundIndex >= 0 Then
'Get the Item from the list (Return Type depends if Datasource was bound
' or List Created)
oFoundItem = cbo.Items(iFoundIndex)
'Use the ListControl.GetItemText to resolve the Name in case the Combo
' was Data bound
sFoundText = cbo.GetItemText(oFoundItem
)
'Append then found text to the typed text to preserve case
sAppendText = sFoundText.Substring(sType
dText.Leng
th)
If PreserveCase Then
cbo.Text = sTypedText & sAppendText
Else
cbo.Text = sFoundText
End If
'Select the Appended Text
cbo.SelectionStart = sTypedText.Length
cbo.SelectionLength = sAppendText.Length
End If
End Sub
Public Sub AutoCompleteCombo_Leave(By
Val cbo As ComboBox)
Dim iFoundIndex As Integer
iFoundIndex = cbo.FindStringExact(cbo.Te
xt)
cbo.SelectedIndex = iFoundIndex
End Sub
Public Sub AutoCompleteCombo_Enter(By
Val cbo As ComboBox)
cbo.SelectionStart = 0
cbo.SelectionLength = Len(cbo.Text)
End Sub