Лучший способ приостановить контрольные события в Windows Forms? - PullRequest
10 голосов
/ 13 ноября 2008

Это кажется очень простой и очень распространенной проблемой. Простейший пример, который я могу придумать, таков:

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

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

Ответы [ 6 ]

6 голосов
/ 13 ноября 2008

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

/*SNIP*/

private bool isMassUpdate;

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

/*SNIP*/

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

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

4 голосов
/ 14 ноября 2008

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

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

3 голосов
/ 13 ноября 2008

Из вашего другого вопроса, я собираюсь догадаться, что вы используете 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, чтобы вернуть обработчики событий. Если все ваши флажки используют один и тот же обработчик, вы можете поместить их в коллекцию и пройтись по коллекции, чтобы добавить или удалить обработчики.

1 голос
/ 03 октября 2014

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

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

1 голос
/ 14 ноября 2008

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

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
1 голос
/ 13 ноября 2008

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

...