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

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

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

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


person Steve Bargelt    schedule 13.11.2008    source источник
comment
Либо/или. Это более общий вопрос, и приведенный выше пример — это просто пример. Я просто много раз сталкивался со сценарием, когда я хотел бы, чтобы события управления останавливались, пока я что-то делаю, и мне просто любопытно, как лучше всего.   -  person Steve Bargelt    schedule 13.11.2008


Ответы (6)


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

/*SNIP*/

private bool isMassUpdate;

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

/*SNIP*/

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

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

person Rob Stevenson-Leggett    schedule 13.11.2008

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

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

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

person Ryan Lundy    schedule 13.11.2008

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

person Will Dean    schedule 13.11.2008
comment
Спасибо, и правда здесь имеет смысл, но это скорее общий вопрос, и приведенный выше пример - это просто пример. Я просто много раз сталкивался со сценарием, когда я хотел бы, чтобы события управления останавливались, пока я что-то делаю, и мне просто любопытно, как лучше всего. - person Steve Bargelt; 13.11.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
person DJ.    schedule 13.11.2008

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

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

person Jim Fred    schedule 03.10.2014