Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I implement incremental search on a listbox?

I want to implement incremental search on a list of key-value pairs, bound to a Listbox.

If I had three values (AAB, AAC, AAD), then a user should be able to select an item in the available list box and type AAC and this item should be highlighted and in focus. It should be also in incremental fashion.

What is the best approach to handle this?

like image 554
Dhanapal Avatar asked Sep 26 '11 14:09

Dhanapal


2 Answers

Add a handler to the KeyChar event (the listbox is named lbxFieldNames in my case):

private void lbxFieldNames_KeyPress(object sender, KeyPressEventArgs e)
{
  IncrementalSearch(e.KeyChar);
  e.Handled = true;
}

(Important: you need e.Handled = true; because the listbox implements a "go to the first item starting with this char" search by default; it took me a while to figure out why my code was not working.)

The IncrementalSearch method is:

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<string>()
    .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;
}

The timeout I implemented is one second, but you can change it by modifying the TimeSpan in the if statement.

Finally, you will need to declare

private string searchString;
private DateTime lastKeyPressTime;
like image 161
Marcel Popescu Avatar answered Nov 17 '22 12:11

Marcel Popescu


If I'm interpreting your question correctly, it seems like you want users to be able to start typing and have suggestions made.

You could use a ComboBox (instead of a ListBox):

  1. Set the DataSource to your list of KeyValuePairs,
  2. Set the ValueMember to "Key" and the DisplayMember to "Value",
  3. Set AutoCompleteMode to SuggestAppend, and
  4. Set AutoCompleteSource to ListItems
like image 4
Grant Winney Avatar answered Nov 17 '22 13:11

Grant Winney