2012-02-21 35 views
7

VB.NET中的组合框的自动完成行为存在问题(使用.NET Framework 2.0)。VB.NET Combobox - 数值自动完成行为

我使用的是组合框的输入数字值,其下拉列表提出可能数字值。该列表按升序排序,例如{“10”,“92”,“9000”,“9001”}。

组合框属性设置如下:

  • AutoCompleteMode:SuggestAppend
  • AutoCompleteSource:listItems中
  • DropDownStyle:下拉
  • 排序:假

下拉列表只是像这样填充:

  • myCombobox.Items.Add( “10”)
  • myCombobox.Items.Add( “92”)
  • myCombobox.Items.Add( “9000”)
  • myCombobox.Items.Add(” 9001“)

当我不输入任何内容时,DropDown列表的值的顺序是正确的,按照原始/升序排列。但是,当我开始键入内容时,DropDown列表中的建议值将按照字母数字排序:如果键入“9”,建议列表将变为{“9000”,“9001”,“92”}。

我想阻止此行为以原始/升序获取列表的值。我不知道如何...

一个可能的解决方法是填充列表中的值为零,例如, {“0010”,“0092”,“9000”,“9001”}但我想避免这种情况。

编辑:

至于建议由bendataclear,可以使用一个列表框中显示建议。 这将适用于小列表,但不能很好地扩展到大列表。它对于某些应用程序可能很有用。基于由bendataclear给出的代码,我把它以这种方式工作:

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 

代码没有经过全面测试,并且可以改善,但主要的想法是存在的。

编辑2:

使用的DataGridView导致更好的性能;对我来说就足够了。谢谢bendataclear。

只是出于好奇,任何其他的答案是欢迎:)

回答

3

似乎是一个问题,当组合框显示的数据,即使你把它重新排序的字母顺序自定义来源:

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 

我觉得我能想到的唯一的办法就是创建自己的自动完成像(未经测试):

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 

编辑:

许多项目一个好的方法(我在应用中使用了10000+):从列表框中一个DataGridView

第一个变化。 然后声明字符串列表,并要自动完成

Dim Numberlist as List<Of String> 

' Fill List using Numberlist.Add("String") 

然后在文本更改属性值填写:

Filter = NumberList.FindAll(AddressOf checkNum) 

DataGridView1.DataSource = Filter 

并添加功能来检查字符串。

Function checkNum(ByVal b As String) As Boolean 

    If b.StartsWith(ComboBox1.Text) Then 
     Return True 
    Else 
     Return False 
    End If 

End Function 

这种方法在我的机器上运行的速度比我输入的快10万个。

+0

谢谢bendataclear。这确实是一种进行的方式。当项目列表增长时,它会变慢。也许可以使用哈希映射根据组合框中输入的文本预先构建所有可能的项目列表,从而避免每次都浏览整个列表。我发现令人惊讶的是,我找不到任何更简单的方法......我已将您的解决方案添加到该问题中。 – DevelBD 2012-04-04 12:48:23

+0

已被加入回答 – bendataclear 2012-04-04 13:06:59

+0

这工作。字符串必须包装在自定义类中,否则只有字符串的长度由DataGridView显示(请参阅http://stackoverflow.com/questions/479329/how-to-bind-a-string-list-to-a -datagrid)。它适用于10K产品,并且适用于我的电脑上的100K产品。谢谢! – DevelBD 2012-04-08 13:43:27