根据用户类型更改 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
我们的 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