Изменение ComboBox SelectedIndex без запуска события в C#

мое приложение c# имеет comboBox с SelectedIndexChanged событие. Обычно я хочу, чтобы это событие сработало, но иногда мне нужно, чтобы событие не сработало. Мой comboBox является списком файлов MRU. Если файл в списке, не существует, то элемент удаляется из comboBox и comboBox SelectedIndex установлено в ноль. Однако, задание comboBox SelectedIndex до нуля вызывает SelectedIndexChanged событие для запуска, что в этом случае проблематично, потому что это приводит к запуску некоторого кода UIF в обработчике событий. Есть есть изящный способ отключить / включить события для элементов управления формой C#? Спасибо.

4 ответов


запустите метод eventhandler с помощью

ComboBox combo = sender as ComboBox;
if (combo.SelectedIndex == 0)
{
    return;
}

Если у вас проблема с другим eventhandler, вы можете сначала удалить регистрацию событий eventhandler.

combo.SelectedIndexChanged -= EventHandler<SelectedIndexChangedEventArgs> SomeEventHandler;
combo.SelectedIndex = 0;
combo.SelectedIndexChanged += EventHandler<SelectedIndexChangedEventArgs> SomeEventHandler;

я сталкивался с этим много раз за эти годы. Мое решение состоит в том, чтобы иметь переменную уровня класса с именем _noise, и если я знаю, что собираюсь изменить индекс combo или любого другого аналогичного элемента управления, который срабатывает при изменении выбранного индекса, я делаю следующее в коде.

private bool _noise;

вот код для обработчика событий элемента управления

private void cbTest_SelectedIndexChange(object sender, EventArgs e)
{
   if (_noise) return;

   // process the events code

   ...

}


затем, когда я знаю, что собираюсь изменить индекс, я делаю следующий:

_noise = true; // cause the handler to ignore the noise...


cbTest.Index = value;


_noise = false;  // let the event process again

Я удивлен, что нет лучшего способа сделать это, но это то, как я это делаю. Я действительно использую Tag поле из элементов управления, поэтому я не придется подкласс элемента управления. И я использую true/null как значения, так как null по умолчанию.

конечно, если вы используете Tag, вам нужно будет сделать это по-другому...

в обработчик:

 private void control_Event(object sender, EventArgs e)
 {
    if (control.Tag != null ) return;

    // process the events code

    ...

 }

в основном коде

 try 
 {
    control.Tag = true;
    // set the control property
    control.Value = xxx;
or
    control.Index = xxx; 
or
    control.Checked = xxx;
    ...
 }
 finally 
 {
    control.Tag = null;
 }

один (довольно уродливый) способ - установить флаг в коде, который удаляет запись, а затем проверить это в SelectedIndexChanged обработчик:

if (!deletedEntry)
{
    // Do stuff
}
deletedEntry = false;

лучшим способом может быть удаление вашего SelectedIndexChanged обработчик событий в начале метода delete и восстановить его в конце. Таким образом, вы не будете знать, что индекс изменился.