I have a problem with the auto-complete behaviour of comboboxes in VB.NET (with the .NET framework 2.0).
I am using a combobox to type in numeric values, and its DropDown list to suggest possible numeric values. This list is sorted in ascending order, for example {"10","92", "9000", "9001"}.
The combobox properties are set as follow:
The DropDown list is simply filled like this:
When I don't type anything, the order of values of the DropDown list is correct, in original/ascending order. However, when I start typing something, the suggested values in the DropDown list get sorted (alphanumerically): if I type "9", the list of suggestions becomes {"9000", "9001", "92"}.
I would like to prevent this behaviour to get the values of the list in the original/ascending order. I can't figure out how...
A possible work-around would be to pad with zeroes the values in the list, e.g. {"0010", "0092", "9000", "9001"} but I would like to avoid this.
Edit:
As suggested by bendataclear, one can use a list box to display the suggestions. This will work for small lists but doesn't scale well to large lists. It may be useful for some applications. Based on the code given by bendataclear, I made it work this way:
Private Sub ComboBox1_KeyUp(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyUp
Dim cursorPos As Integer = ComboBox1.SelectionStart
ListBox1.Items.Clear()
For Each s In ComboBox1.Items
If s.StartsWith(ComboBox1.Text) Then
ListBox1.Items.Add(s)
End If
Next
If ListBox1.Items.Count > 0 And ComboBox1.Text.Length > 0 Then
ComboBox1.Text = ListBox1.Items(0)
ComboBox1.SelectionStart = cursorPos
ComboBox1.SelectionLength = 0
End If
End Sub
The code has not been thoroughly tested and can be improved, but the main idea is there.
Edit 2:
Using DataGridView leads to better performance; it was sufficient for me. Thanks bendataclear.
Just out of curiosity, any other answer is welcomed :)
Seems to be an issue when the combo box displays the data, as even if you set a custom source it re-orders alphabetically:
ComboBox1.Items.Add("10")
ComboBox1.Items.Add("92")
ComboBox1.Items.Add("9000")
ComboBox1.Items.Add("9001")
ComboBox1.AutoCompleteCustomSource.Add("10")
ComboBox1.AutoCompleteCustomSource.Add("92")
ComboBox1.AutoCompleteCustomSource.Add("9000")
ComboBox1.AutoCompleteCustomSource.Add("9001")
ComboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource
I think the only way I can think of is to create your own autocomplete something like (untested):
Dim cbotxt As String = ComboBox1.Text
Dim key As String
key = ChrW(e.KeyCode)
ListBox1.Items.Clear()
For Each i In ComboBox1.Items
Dim s As String = i.ToString()
If s.StartsWith(ComboBox1.Text & key) Then
ListBox1.Items.Add(s)
End If
Next
If ListBox1.Items.Count > 0 Then
ListBox1.Visible = True
ComboBox1.Text = ListBox1.Items(0)
End If
Edit:
A good approach for many items (I'm using for 10000+ in an application):
First change from a list box to a datagridview. Then declare a list of strings and fill with values you want to autocomplete
Dim Numberlist as List<Of String>
' Fill List using Numberlist.Add("String")
Then in the text change property:
Filter = NumberList.FindAll(AddressOf checkNum)
DataGridView1.DataSource = Filter
And add the function to check the strings.
Function checkNum(ByVal b As String) As Boolean
If b.StartsWith(ComboBox1.Text) Then
Return True
Else
Return False
End If
End Function
This method runs on my machine with 10k items faster than I can type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With