根据用户类型更改 CheckedListBox 中的选择

Change selection in CheckedListBox as user types

我们的 VB.NET 应用程序中有一个多 select 复选框的自定义实现。它在很大程度上工作得很好,但我们最近用这个控件替换了一个常规的单一 select ComboBox,它不支持在键入时搜索。

例如,如果用户想要进入“zygote”,他们过去可以开始输入这个词,它会慢慢靠近。现在,当您键入时,它会跳转到 z,然后是 y,然后是 g,依此类推。
是否可以让它像使用标准 ComboBox 一样运行?

现在,我捕获了 KeyDown 和 KeyUp,因此它不会在他们键入时无关地 select 一个项目,但这不是理想的最终解决方案。

如评论中所述,计时器可以工作,但我会忽略它(因为又旧又无聊:),我将使用 Stopwatch 代替:

每次生成 KeyDown 事件时都会重新启动秒表。
按下的键被添加到 StringBuilder 对象(以避免创建大量字符串)。当按键之间的时间大于预定义的值时,将清除 StringBuilder 容器:在这里,我将其设置为 400ms,以测试或添加配置选项。

► 双 StringBuilder.Append() 是为了保留默认行为:当按下具有 long 延迟的按键时,它会迭代以相同字母开头的项目(或多或少是文件资源管理器所做的)。

KeyDown 处理程序添加到表单的 Sub New() 中(到名为 checkedList1 的 CheckedListBox)。它可用于处理 Form 中的任何 ListBox 或 CheckedListBox。

Imports System.Diagnostics
Imports System.Text

Sub New() 
    AddHandler checkedList1.KeyDown, AddressOf listBox_KeyDown
End Sub

Private swLb As New Stopwatch()
Private sbCLb As New StringBuilder()

Private Sub listBox_KeyDown(sender As Object, e As KeyEventArgs)
    Dim checkedList = DirectCast(sender, ListBox)
    If e.KeyCode < Keys.A Then Return
    If swLb.ElapsedMilliseconds > 400 Then
        sbCLb.Clear()
        sbCLb.Append(ChrW(e.KeyData))
        swLb.Restart()
        Return
    End If
    e.SuppressKeyPress = True
    sbCLb.Append(ChrW(e.KeyData))
    Dim idx = checkedList.FindString(sbCLb.ToString())
    checkedList.SelectedIndex = If(idx = ListBox.NoMatches, checkedList.SelectedIndex, idx)
    swLb.Restart()
End Sub