С# WinForms ListBox Инкрементный поиск с парами ключ/значение в качестве элементов списка

Я искал ответ, и хотя есть тот, который работает при использовании списка с элементами строки типа, я не могу понять, как конвертировать, когда мои элементы имеют тип

KeyValuePair<string, ChangeRec>

Я хочу иметь возможность выполнять поиск по мере ввода списка (не могу использовать ComboBox, поскольку элемент управления должен иметь определенный размер в форме), выполняя поиск по ключевому (текстовому) элементу. Спасибо @Marcel Popescu за отправную точку. Вот моя версия кода (прокомментирован только над строкой, где он терпит неудачу, так как он правильно не может преобразовать элемент kvp в строку):

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;
}

person MartinS    schedule 03.08.2016    source источник
comment
Как заполнить ListBox? Этот код необходим для понимания того, что здесь не работает.   -  person Steve    schedule 03.08.2016
comment
Извините, я забыл включить эту информацию. Данные (словарь) привязаны к источнику данных элемента управления, а DisplayMember имеет значение Key, а ValueMember — значение. Данные считываются из текстового файла. Ключ элемента — это имя файла, а значение элемента — объект, содержащий всю информацию об этом файле.   -  person MartinS    schedule 03.08.2016


Ответы (1)


Используйте это, я предполагаю, что это Key из KeyValuePair, в котором вы хотите искать:

//* 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;

Поскольку KeyValuePair является типом значения, он никогда не может быть нулевым. Чтобы узнать, присвоено ли ему значение, мы проверяем с помощью item.Equals(default(KeyValuePair<string, ChangeRec>))

person sachin    schedule 03.08.2016
comment
Я пробовал это, но пропустил, что мне нужно было использовать KeyValuePair‹string, ChangeRec› внутри приведения. Спасибо. Теперь я получаю сообщение об ошибке на следующей строке (if (item == null) return;), потому что kvp нельзя сравнить с нулем. - person MartinS; 03.08.2016