Два элемента управления правильно ссылаются друг на друга

#c# #winforms #c#-4.0 #circular-dependency

#c# #winforms #c #-4.0 #циклическая зависимость

Вопрос:

У меня есть поле со списком и элемент управления DateTimePicker в приложении .net forms. Желаемая функциональность для взаимосвязи двух элементов управления заключается в том, что модификация одного приведет к изменению значения в другом. Логика изменения другого элемента управления содержится в каждом событии изменения элементов управления; Поле со списком «SelectedIndexChanged» и DateTimePicker «Изменены», и это выглядит примерно следующим образом:

 othercontrol.value = value;
  

Есть ли четкий способ, которым я могу изолировать события изменения от соответствующих элементов управления, чтобы определить, были ли они отправлены пользовательским интерфейсом или событие изменения другого элемента управления для прекращения цикла, которое вызовет текущая настройка?

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

Ответ №1:

Вы можете удалить eventhandler элемента управления перед настройкой его значения и добавить его обратно сразу после установки значения.

 othercontrol.SelectedChanged -= othercontrol_SelectedChanged;
othercontrol.value = value;
othercontrol.SelectedChanged  = othercontrol_SelectedChanged;
  

Ответ №2:

Тогда попробуйте это.

Хорошо, это немного халтурно, но это сработало бы:

 private bool eventBubbledDate = false;
private bool eventBubbleCombi = false;

protected override MyCombi_OnChange(object sender, eventargs e)
{
  if (eventBubbledDate)
  {
    eventBubbledDate = false;
    return;
  }
  eventBubbleCombi = true;
  myDateTime.Value = myCombi.SelectedValue;
}

protected override MyDateTime_OnChange(object sender, eventargs e)
{
  if (eventBubbleCombi )
  {
     eventBubbleCombi = false;
     return;
  }

  // process DateStuff here
  // update other control
  eventBubbledDate = true;
}
  

В качестве альтернативы, вы могли бы использовать перечисление для отслеживания состояния вместо использования логических «флагов», но я думаю, что bools проще продемонстрировать.

Комментарии:

1. Похоже, отправителем всегда является сам элемент управления, DateTimePicker для события изменения DateTimePicker.

2. Я проверю это. Это может занять немного времени. Большое спасибо за вашу помощь! Я дам вам знать.

3. Оба ответа сработали, но для удаления метода из события потребовалось меньше кода. Большое спасибо за вашу помощь.

4. Я бы настоятельно призвал к небольшой осторожности, удаление события и его повторное добавление может привести к трудноотлаживаемым условиям гонки в других, казалось бы, не связанных областях. Например, что, если у вас есть несколько событий, поставленных в очередь, потому что Windows отдает приоритет другой задаче, но ваше событие запускает и удаляет обработчик только для того, чтобы Windows снова не торопилась … пытаться отладить эти вещи — сплошная мука, вот почему я не упомянул об этом и почему состояние записи похоже на то, как Windows и сама .net делают это внутренне.

5. Спасибо за предупреждение. Я приму это во внимание.