如何在列表框上实现增量搜索?
我想在绑定到Listbox的键值对列表上实现增量搜索。
如果我有三个值(AAB,AAC,AAD),则用户应该能够在可用列表框中选择一个项目并键入AAC,并且该项目应突出显示并处于焦点。 它也应该是渐进的方式。
处理这个问题的最佳方法是什么?
我意识到这已经很晚了……但是,刚刚实施了这个,我会把它放在这里,希望能帮助别人。
向KeyChar事件添加处理程序(在我的情况下,列表框被命名为lbxFieldNames):
private void lbxFieldNames_KeyPress(object sender, KeyPressEventArgs e) { IncrementalSearch(e.KeyChar); e.Handled = true; }
(重要的是:你需要e.Handled = true;
因为列表框默认实现了“转到以此char开头的第一个项目”搜索;我花了一些时间来弄清楚为什么我的代码不起作用。)
IncrementalSearch方法是:
private void IncrementalSearch(char ch) { if (DateTime.Now - lastKeyPressTime > new TimeSpan(0, 0, 1)) searchString = ch.ToString(); else searchString += ch; lastKeyPressTime = DateTime.Now; var item = lbxFieldNames .Items .Cast() .Where(it => it.StartsWith(searchString, true, CultureInfo.InvariantCulture)) .FirstOrDefault(); if (item == null) return; var index = lbxFieldNames.Items.IndexOf(item); if (index < 0) return; lbxFieldNames.SelectedIndex = index; }
我实现的超时是一秒钟,但您可以通过修改if
语句中的TimeSpan
来更改它。
最后,您需要申报
private string searchString; private DateTime lastKeyPressTime;
希望这可以帮助。
如果我正确地解释您的问题,您似乎希望用户能够开始输入并提出建议。
您可以使用ComboBox(而不是ListBox):
- 将DataSource设置为KeyValuePairs列表,
- 将ValueMember设置为“Key”,将DisplayMember设置为“Value”,
- 将AutoCompleteMode设置为SuggestAppend,和
- 将AutoCompleteSource设置为ListItems
您可以在用户输入字符时使用TextChanged
事件触发,也可以使用listbox
事件DataSourceChanged
将其hover在特定项目或任何您想要的内容上。
我会举个例子:
private void textBox1_TextChanged(object sender, EventArgs e) { listBox1.DataSource = GetProducts(textBox1.Text); listBox1.ValueMember = "Id"; listBox1.DisplayMember = "Name"; } List GetProducts(string keyword) { IQueryable q = from p in db.GetTable () where p.Name.Contains(keyword) select p; List products = q.ToList (); return products; }
因此,每当用户开始输入任何char时, getproducts
方法就会执行并填充列表框,默认情况下,将列表框中的第一个项目hover在你可以处理的列表框事件DataSourceChanged
以执行您想要执行的任何操作。
还有另一种有趣的方法,即: TextBox.AutoCompleteCustomSource
属性 :
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource; AutoCompleteStringCollection stringCollection = new AutoCompleteStringCollection(); textBox1.AutoCompleteCustomSource = stringCollection;
此列表只能使用string[]
,因此您可以从数据源获取它们,然后当文本textbox
的文本发生更改时,将数据源中的相似单词添加到文本框自动完成自定义源中:
private void textBox1_TextChanged(object sender, EventArgs e) { listBox1.Items.Clear(); if (textBox1.Text.Length == 0) { listbox1.Visible = false; return; } foreach (String keyword in textBox1.AutoCompleteCustomSource) { if (keyword.Contains(textBox1.Text)) { listBox1.Items.Add(keyword); listBox1.Visible = true; } } }
添加另一个事件ListBoxSelectedindexchanged
以将所选文本添加到文本框中
也许你可以在用户输入的控件上添加一个TextChanged
事件来搜索(我猜一个TextBox
)。 在这种情况下,您可以遍历所有项目以搜索与用户键入的单词最相对应的项目。