Кнопка временного отключения - PullRequest
4 голосов
/ 07 апреля 2011

Должно быть просто, но ...:)

У меня есть только одна кнопка на форме.Кнопка вызывает функцию, выполнение которой занимает 10 секунд (например).Я хотел бы временно отключить кнопку в течение этого времени, чтобы, если пользователь нажал клавишу Enter во время выполнения функции, ничего не произошло.

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

Мой код:

private void button1_Click(object sender, EventArgs e)
{
    Debug.WriteLine("Click");
    button1.Enabled = false;
    Thread.Sleep(3000); // simulate something...
    button1.Enabled = true;
    button1.Focus();
}

Редактировать: функция печатает что-то на принтере.С помощью функции API принтера я могу определить, когда печать была завершена, только после этого можно снова активировать кнопку.

Ответы [ 3 ]

4 голосов
/ 23 июля 2012

У меня недавно была такая же проблема, и я решил опубликовать свое объяснение:

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

Исправить предложение:

Вы можете вставить строку «Application.DoEvents ()» простоперед строкой "button1.Enabled = true;"Таким образом, поставленные в очередь сообщения будут достигать кнопки, пока она все еще отключена, и теперь кнопка будет отбрасывать их.

Отказ от ответственности: Кажется, использование Application.DoEvents () не считается хорошей практикой.Однако это хорошо показывает, что происходит в данном конкретном случае.

Я думаю, что решение, предложенное Rhapsody, лучше, чем использование Application.DoEvents ().С помощью BackgroundWorker мы создаем второй поток и поэтому не блокируем поток с графическим интерфейсом.Поскольку GUI остается отзывчивым, отключение кнопки будет работать, как и ожидалось.

1 голос
/ 07 апреля 2011

Если вы знаете, что выполнение операции займет больше времени (например,> 5 секунд), возможно, лучше выполнить это действие асинхронно.

Так что в этом случае возьмите BackgroundWorker .Вы можете легко отключить кнопку перед запуском BackgroundWorker и снова включить ее в событии Completed.

0 голосов
/ 07 апреля 2011

Попробуйте этот код.

AutoResetEvent _autoResetEvent = new AutoResetEvent(false);

private button1_click(object o, EventArgs e)
{
    button1.Enabled = false;
    DoPrinterJob();
    button1.Enabled = _autoResetEvent.WaitOne();
}

private void DoPrinterJob()
{
    //Do something.
    _autoResetEvent.Set();
}

Надеюсь, это поможет.

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