Change selection in CheckedListBox as user types

ぐ巨炮叔叔 提交于 2019-12-24 04:57:09

问题


We have a custom implementation of a multi-select checkbox in our VB.NET application. It largely works just fine, but we recently replaced a regular single-select combobox with this control, and it does not support searching while typing.

For example, if the user wants to get to "zygote" they used to be able to start typing the word, and it would slowly get closer. Now, as you type, it jumps to the z's, then the y's, then the g's, and so on. Is it possible to make it behave as it did with a standard combobox?

For now, I capture KeyDown and KeyUp so it does not extraneously select an item as they type, but this is not the ideal final solution.


回答1:


As described in the comments, a Timer can work, but I'll dismiss it (because old and boring :) and I'll make use of a Stopwatch instead:

The Stopwatch is restarted each time a KeyDown event is generated.
The keys pressed are added to a StringBuilder object (to avoid the creation of a multitude of strings). The StringBuilder container is cleared when the time between key presses is greater than a predefined value: here, I've set it to 400ms, to test or add a configuration option.

► The double StringBuilder.Append() is there to preserve the default behavior: when keys are pressed with a long delay, it iterates the Items that begin with the same letter (more or less what File Explorer does).

The KeyDown handler is added in the Form's Sub New(), here (to a CheckedListBox named checkedList1). It can be used to handle any ListBox or CheckedListBox in the Form.

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


来源:https://stackoverflow.com/questions/59313953/change-selection-in-checkedlistbox-as-user-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!