MartinS MartinS - 2 months ago 26
C# Question

C# WinForms ListBox Incremental Search with Key/Value Pairs as ListItems

I've searched for an answer, and whilst there is one that works when using a listbox with items of type string, I can't figure out how to convert when my items are of type

KeyValuePair<string, ChangeRec>

I want to be able to search as I type in the listbox (cannot use ComboBox as the control needs to be a specific size on the form), searching by the key (Text) item. Thanks to @Marcel Popescu for the starting point. Here's my version of the code (have commented only above the line where it fails, as it rightly can't cast a kvp item as string):

private string searchString;
private DateTime lastKeyPressTime;

private void lbElementNames_KeyPress(object sender, KeyPressEventArgs e)
e.Handled = true;

private void IncrementalSearch(char ch)
if ((DateTime.Now - this.lastKeyPressTime) > new TimeSpan(0, 0, 1))
this.searchString = ch.ToString();
this.searchString += ch;
this.lastKeyPressTime = DateTime.Now;
//* code falls over HERE *//
var item =
.FirstOrDefault(it => it.StartsWith(this.searchString, true, CultureInfo.InvariantCulture));

if (item == null) return;
var index = this.lbElementNames.Items.IndexOf(item);
if (index < 0) return;
this.lbElementNames.SelectedIndex = index;


Use this, I am assuming it is the Key of KeyValuePair that you want to search in:

//* code falls over HERE *//

var item =
        this.lbElementNames.Items.Cast<KeyValuePair<string, ChangeRec>>()
            .FirstOrDefault(it => it.Key.StartsWith(this.searchString, true, CultureInfo.InvariantCulture));

if (item.Equals(default(KeyValuePair<string, ChangeRec>))) return;

As KeyValuePair is a value type, it can't ever be null. To find out whether it has been assigned a value, we check by using item.Equals(default(KeyValuePair<string, ChangeRec>))