Лучший способ приостановить события управления в Windows Forms?

StackOverflow https://stackoverflow.com/questions/287595

  •  08-07-2019
  •  | 
  •  

Вопрос

Кажется, это очень простая и очень распространенная проблема.Самый простой пример, который я могу придумать, это:

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

Я не могу найти событие управления приостановкой всей формы.Если мне это просто не хватает, тогда отличный простой ответ.За исключением простого решения, которое мне просто не хватает, каков наилучший способ (лучшая практика?принятое решение?) приостановить события управления формой?

Это было полезно?

Решение

Я сталкивался с этим раньше и обычно видел, как люди делают это:

/*SNIP*/

private bool isMassUpdate;

public void Check1_Check(object sender, EventArgs e)
{
   if(!isMassUpdate)
   {
       do some stuff
   }
}

/*SNIP*/

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

Информация об утечках памяти и обработчиках событий:Они не связаны напрямую с присоединением и отсоединением, но в одном из наших приложений мы видели, что это может быть вызвано неправильным обращением обработчиков событий к деревьям наследования.

Другие советы

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

Еще одна полезная вещь: если мне нужно приостановить события в блоке, я создаю небольшой вспомогательный класс, который IDisposable, который я могу использовать в " using " блок (в C #), поэтому я не забываю уменьшить счетчик, как только я выйду из области видимости.

Из вашего другого вопроса, я собираюсь догадаться, что вы используете VB .NET. Итак, RemoveHandler - ваш лучший выбор. Обычно в VB люди устанавливают обработчики событий, используя предложение Handles. Но вы также можете сделать это следующим образом:

AddHandler chk1.CheckedChanged, AddressOf DoSomething

где DoSomething может выглядеть так:

Private Sub DoSomething(ByVal sender As Object, ByVal e As EventArgs)
    ' whatever
End Sub

AddHandler подключает событие, чтобы оно сработало. Чтобы он не срабатывал, используйте RemoveHandler:

RemoveHandler chk1.CheckedChanged, AddressOf DoSomething

Перед обновлением свойства Checked своих дочерних флажков вызовите RemoveHandler для каждого из них; затем, когда вы закончите, вызовите AddHandler, чтобы вернуть обработчики событий. Если все ваши флажки используют один и тот же обработчик, вы можете поместить их в коллекцию и пройтись по коллекции, чтобы добавить или удалить обработчики.

Можно также рассмотреть возможность обработки событий нажатия кнопок для кнопок, а не для проверки изменений. Это может быть ближе к вашим намерениям.

В моем Visual Basic 6.0 приложении мне приходилось обрабатывать пользователей, дважды щелкающих < em> все , поэтому во всех моих обработчиках событий у меня есть одна строка, которая проверяет глобальную переменную

Private bSuspendEvents as Boolean

Private Sub Button1_Click()

    On Error Goto ErrorHandler

    If bSuspendEvents then Exit Sub

    bSuspendEvents = True

    'Do stuff

    NormalExit:
        bSuspendEvents = False
        Exit Sub

    ErrorHandler:
        'Handle Error
        Resume NormalExit

End Sub

См. вопрос переполнения стека Как игнорировать простые события, возникающие при изменении состояний элементов управления в C # Windows Forms?

  

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top