Кнопка отключить и включить - PullRequest
9 голосов
/ 23 января 2012

У меня есть приложение для Windows на базе vb.net, где при нажатии кнопки «GO» в БД загружается куча данных. Так что в моем приложении, как только нажата кнопка «GO», я хочу просто отключить ее и хотел бы включить ее обратно, когда загрузка будет завершена. Теперь в моем конкретном методе для btnGo_Click () у меня есть:

btnGo.Enabled = False

в качестве первой строки и

btnGo.Enabled = True

как последняя строка в том же методе.

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

Пожалуйста, подскажите, что я делаю не так?

Редактировать (от 25 января 2012 г.): я внес изменения в соответствии с предложением наших коллег, но здесь я столкнулся с новой проблемой. Я столкнулся с проблемой, когда текстовое поле обновляется, но не всегда. Я обновил свое текстовое поле в событии "_ProgressChanged" фонового рабочего потока. В моем случае, если загружено 10 записей. Затем в texbox ожидаются 10 строк обновлений. Но только несколько строк отображаются в текстовом поле. Это снова проблема перекраски? Пожалуйста, предложите ... Потому что все остальное сделано согласно вашему предложению

Ответы [ 6 ]

16 голосов
/ 23 января 2012

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

Это объясняет, почему, если вы забудете reenable кнопку управления в конце метода обработчика событий, она все еще отключена -потому что вы сказали отключить кнопку в первой строке метода.

Это классический случай, когда вам никогда не следует выполнять длительные вычислительные задачи внутри метода обработчика событий, потому что он блокирует пользовательский интерфейсот обновления.На самом деле вычисление должно происходить в отдельном потоке.Но не пытайтесь создать поток вручную, и определенно не пытайтесь обновить свой интерфейс из отдельного потока.Вместо этого используйте BackgroundWorker компонент для автоматической обработки всего этого за вас.В связанной документации MSDN есть отличный пример того, как ее использовать.

Отключите кнопку перед запуском BackgroundWorker, а затем повторно включите ее в событии Completed, сигнализируя о завершении загрузки базы данных..

3 голосов
/ 23 января 2012

Поскольку вы пытаетесь выполнить функцию, которая может занять некоторое время, я бы посоветовал вам использовать многопоточность.В .NET есть компонент BackgroundWorker , который отлично подходит для выполнения асинхронных задач.

При нажатии кнопки вызовите BackgroundWorker следующим образом:

if not bgwWorker.IsBusy then
   btnGo.enabled = false
   bgwWorker.RunWorkerAsync()
end if 

и используйте завершенное событие, чтобы снова активировать кнопку:

Private Sub bgwWorker_DoWork(ByVal sender As System.Object, _
                 ByVal e As System.ComponentModel.DoWorkEventArgs) _
                 Handles bgwWorker.DoWork
' Do your things    
End Sub

Private Sub bgwWorker_RunWorkerCompleted(ByVal sender As System.Object, _
                         ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
                         Handles bgwWorker.RunWorkerCompleted
' Called when the BackgroundWorker is completed.
btnGo.enabled = true
End Sub

В приведенном выше примереЯ использовал bgwWorker как экземпляр BackgroundWorker.

0 голосов
/ 25 ноября 2014

Обычно не очень хорошая идея управлять состоянием кнопки отправки. Вместо этого выполните проверку при отправке.

0 голосов
/ 08 января 2014

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

Решение, как уже предлагали другие, заключается в использовании Backgroundworker.

Не пытайтесь использовать doEvents () в качестве решения (никогда не делайте), так как это может привести к возникновению других тонких проблем. Тем не менее, вы можете доказать приведенное выше объяснение с помощью некоторых экспериментальных doEvents в вашем коде. Вы увидите, что щелчок отбрасывается, если выполнить doEvents до повторного включения кнопки. С другой стороны, выполнение doEvents непосредственно после button.disable (для «обновления GUI») не поможет, если оно выполняется до щелчка.

0 голосов
/ 23 января 2012

Я только что попытался отключить кнопку, Update в форме, Sleep, и снова включить ее. Он все еще выполнял щелчок (щелчок, который был выполнен, пока он «спал» с отключенной кнопкой) после того, как он был включен.

Я предполагаю, что формы "помнят" клики.

(РЕДАКТИРОВАТЬ: я сделал это в C #.)

0 голосов
/ 23 января 2012

Если ваш btnGo_Click() запускается в основном потоке, пользовательский интерфейс не может быть корректно обновлен внутри трудоемкой задачи.
Лучший способ сделать то, что вам нужно, - запустить ваш метод в BackgroundWorker .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...