当有多个以相同字符开头的项目时,有没有人可以告诉我应该以编程方式使用键盘选择列表框中的项目。 例如,
如果我想通过输入o,n,c来关注“一次”,我该怎么办?而不是从一个项目跳到另一个项目而不是默认行为。
答案 0 :(得分:4)
将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;
}
希望这有帮助! ;)
<强> EDIT2:强>
我不知道您是否注意到e.Handled
的重要评论。默认情况下,如果按ListBox中的某个键,控件将选择具有该键字符的第一个找到的项目。但它没有我的代码所具有的功能。因此,如果您远程e.Handled
行,代码将起作用,但控件也将处理按键,您不希望:项目将无法正确选择!
答案 1 :(得分:3)
您想使用LBS_SORT
list box style。创建控件后无法应用此样式,因此要添加此样式,您需要覆盖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;
}
}
}
此列表框现在应该对列表中的项目进行排序。支持增量搜索(你不能关闭排序我害怕,如果你需要控制排序顺序,那么你需要自己进行增量搜索,如阿巴斯建议的那样)
更新:如果您另外删除了LBS_USETABSTOPS
样式,您甚至会看到一个编辑carret,显示增量搜索当前匹配的字符
答案 2 :(得分:0)
我刚刚为我的案例修改了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
}