VB.NET Combobox

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:

  • AutoCompleteMode: SuggestAppend
  • AutoCompleteSource: ListItems
  • DropDownStyle: DropDown
  • Sorted: False
  • The DropDown list is simply filled like this:

  • myCombobox.Items.Add("10")
  • myCombobox.Items.Add("92")
  • myCombobox.Items.Add("9000")
  • myCombobox.Items.Add("9001")
  • 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, eg {"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.

    链接地址: http://www.djcxy.com/p/10466.html

    上一篇: 使Adsense响应

    下一篇: VB.NET组合框