0

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)
{
    this.IncrementalSearch(e.KeyChar);
    e.Handled = true;
}

private void IncrementalSearch(char ch)
{
    if ((DateTime.Now - this.lastKeyPressTime) > new TimeSpan(0, 0, 1))
    {
        this.searchString = ch.ToString();
    }
    else
    {
        this.searchString += ch;
    }
    this.lastKeyPressTime = DateTime.Now;
    //* code falls over HERE *//
    var item =
        this.lbElementNames.Items.Cast<string>()
            .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;
}
MartinS
  • 111
  • 1
  • 14
  • How do you fill the ListBox? That code is essential to understand what is not working here. – Steve Aug 03 '16 at 08:00
  • Apologies, I forgot to include that info. The data (a dictionary) is bound to the control's datasource and the DisplayMember is set to Key, the ValueMember set to Value. The data is read from a text file. The item key is a filename, and the item value is an object which contains all the info on that file. – MartinS Aug 03 '16 at 08:16

1 Answers1

1

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>))

sachin
  • 2,341
  • 12
  • 24
  • I tried that but missed that i needed to use KeyValuePair inside the cast. Thanks. I'm getting an error at the next line now (if (item == null) return;) because the kvp can't be compared to null. – MartinS Aug 03 '16 at 08:20