winforms “键入搜索”与vb.net winform列表框?

cidc1ykv  于 8个月前  发布在  .NET
关注(0)|答案(1)|浏览(72)

在许多应用程序中,您可以通过键入前几个字符来快速查找列表中的项目。
例如,假设我有一个数据绑定列表,其中有六个名称:Aaron,Allison,Abdul,Bob,Orville and Peter”.如果我在键盘上键入“Ab”,我希望列表跳转到“Abdul”。如果我输入“Aaa”,我希望它跳到Allison(“a”代表Aaron,“a”再次代表Aaron中的第二个字母,然后最后一个“a”跳到Allison)
但是我在vb.net上似乎做不到这一点。当我在列表框中输入“Ab”时,选中的项目从Aaron跳到Bob,而输入“Aa”则从Aaron直接跳到Allison。
WPF具有TextSearch.TextPath属性,它允许您使用数据表上的列(例如,“FirstName”),但我似乎在WinForms中找不到等效的。我知道我可以添加一个行过滤器和一个文本框,和/或我可以使用一个变量,一个计时器和一些代码来跟踪按下了什么,然后清除变量,如果没有键入几秒钟,但我想知道是否有一个更好的方法来做到这一点。
那么,有办法做到这一点吗?

yxyvkwin

yxyvkwin1#

“不,我不知道,我也不知道。
我可以这样做

Private names As List(Of String)
Private keystrokes As New List(Of Char)()
Private processTimer As New System.Threading.Timer(AddressOf processAction, Nothing, -1, -1)

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    names = {"Aaron", "Allison", "Abdul", "Bob", "Orville"}.OrderBy(Function(s) s).ToList()
    ListBox1.DataSource = names
End Sub

Private Sub ListBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles ListBox1.KeyPress
    e.Handled = True
    keystrokes.Add(e.KeyChar)
    processTimer.Change(250, -1)
End Sub

Private Sub processAction(state As Object)
    Dim searchString = New String(keystrokes.ToArray()).ToUpper()
    keystrokes.Clear()
    Dim match = names.FirstOrDefault(Function(name) name.ToUpper().StartsWith(searchString))
    If match = "" Then
        SelectListboxIndex(names.Concat({searchString}).OrderBy(Function(name) name).ToList().FindIndex(Function(name) name.ToUpper() = searchString.ToUpper()))
    Else
        SelectListboxIndex(names.FindIndex(Function(name) name.ToUpper() = match.ToUpper()))
    End If
End Sub

Private Sub SelectListboxIndex(index As Integer)
    If ListBox1.InvokeRequired Then
        ListBox1.Invoke(New Action(Of Integer)(AddressOf SelectListboxIndex), index)
    Else
        ListBox1.SelectedIndex = Math.Max(Math.Min(index, ListBox1.Items.Count - 1), 0)
    End If
End Sub

不知道为什么要aaa选择Allison,但逻辑可以修改。

相关问题