谁能告诉我当有多个以相同字符开头的项目时,我应该以编程方式做什么才能使用键盘选择列表框中的项目。例如,
- 一
- 二
- 三
- 一次
- 橙子
如果我想通过输入 o,n,c 来关注“Once”,我应该怎么做?而不是从一个项目跳到另一个项目,而不是默认行为。
谁能告诉我当有多个以相同字符开头的项目时,我应该以编程方式做什么才能使用键盘选择列表框中的项目。例如,
如果我想通过输入 o,n,c 来关注“Once”,我应该怎么做?而不是从一个项目跳到另一个项目,而不是默认行为。
将 KeyPress 事件处理程序添加到 ListBox 并跟踪按下的键。然后将已键入的完整值与 ListBox 中的项目的值进行比较。如果有匹配项,请选择该项目。
编辑:
这是我创建的一个有效的解决方案。我还测量了按键之间的时间。这样,如果两次按键之间的时间超过 1.5 秒,则搜索字符串将被清空并用最后一个搜索字符重新填充。之后就像我说的:找到一个匹配项,如果有匹配项,请选择该项目。这两个私有字段是类级别的字段,用于跟踪最后一次按键的时间,字符串用于存储搜索字符串。
private DateTime _lastKeyPress;
private string _searchString;
private void ListBox1KeyPress(object sender, KeyPressEventArgs e)
{
var newDate = DateTime.Now;
var diff = newDate - _lastKeyPress;
if (diff.TotalSeconds >= 1.5)
_searchString = string.Empty;
_searchString += e.KeyChar;
for (var i = 0; i < listBox1.Items.Count; i++)
{
var item = listBox1.Items[i].ToString();
if (item.ToLower().StartsWith(_searchString))
{
listBox1.SelectedItem = item;
break;
}
}
_lastKeyPress = newDate;
e.Handled = true; //REALLY IMPORTANT TO HAVE THIS
}
这是一个使用 LinQ 来匹配搜索项的示例:
private void ListBox1KeyPress(object sender, KeyPressEventArgs e)
{
var newDate = DateTime.Now;
var diff = newDate - _lastKeyPress;
if (diff.TotalSeconds >= 1.5)
_searchString = string.Empty;
_searchString += e.KeyChar;
var found = listBox1.Items.Cast<object>().Select(t => t.ToString()).Where(item => item.ToLower().StartsWith(_searchString)).FirstOrDefault();
if(!String.IsNullOrEmpty(found))
listBox1.SelectedItem = found;
_lastKeyPress = newDate;
e.Handled = true;
}
希望这可以帮助!;)
编辑2:
不知道大家有没有注意到评论的重要性e.Handled
。默认情况下,如果您按下 ListBox 中的某个键,控件将选择第一个找到的具有该键字符的项。但它没有我的代码所具有的功能。因此,如果您远程控制e.Handled
线路,代码将起作用,但控件也会处理按键,而您不希望这样:项目不会被正确选择!
您想使用LBS_SORT
列表框样式。创建控件后无法应用此样式,因此要添加此样式,您需要覆盖该CreateParams
属性。创建一个SortedListBox
派生自ListBox
并覆盖此属性的类(让我们调用它),如下所示
public class MyListBox : ListBox
{
protected override CreateParams CreateParams
{
get
{
var returnValue = base.CreateParams;
returnValue.Style |= 0x2; // Add LBS_SORT
returnValue.Style ^= 128; // Remove LBS_USETABSTOPS (optional)
return returnValue;
}
}
}
这个列表框现在应该对列表中的项目进行排序并支持增量搜索(恐怕你不能关闭排序,如果你需要控制排序顺序,那么你需要自己进行增量搜索,就像 Abbas已建议)
更新:如果您另外删除了LBS_USETABSTOPS
样式,您甚至会得到一个编辑框,显示增量搜索当前匹配的字符
我刚刚为我的案例修改了 Abbas 代码。这是我的桌面程序,并以其中一种具有 ListBox 控件的形式使用。这对我很有用。感谢阿巴斯
private DateTime _lastKeyPress;
private string _searchString;
private void lstEmployer_KeyPress(object sender, KeyPressEventArgs e)
{
var newDate = DateTime.Now;
var diff = newDate - _lastKeyPress;
if (diff.TotalSeconds >= 2)
_searchString = string.Empty;
_searchString += e.KeyChar;
lstEmployer.SelectedIndex = lstEmployer.FindString(_searchString);
_lastKeyPress = newDate;
e.Handled = true; //REALLY IMPORTANT TO HAVE THIS
}