Как остановить нажатие кнопки Windows Forms дважды - PullRequest
1 голос
/ 09 июня 2009

У меня есть кнопка Windows Forms на форме, которая отправляет веб-запрос. Я хочу иметь возможность отключить кнопку при первом нажатии, а затем повторно включить ее, когда я получу ответ. У меня нет большого контроля над кодом, который вызывается, и тем, как он вызывается, поэтому все, с чем я могу поиграть, это события Button, или я могу создать свою собственную кнопку, которая наследуется от Button следующим образом:

public class SingleClickButton : Button
{
    protected override void OnClick(EventArgs e)
    {
        bool wasEnabled = this.Enabled;
        this.Enabled = false;

        if (wasEnabled)
        {
            base.OnClick(e);
        }
    }
}

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

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

Ответы [ 5 ]

7 голосов
/ 09 июня 2009

Вам нужно использовать этот сценарий:

public class SingleClickButton : Button
{
        protected override void OnClick(EventArgs e)
        {
                this.Enabled = false;
                RunAsynchronousMethod( CallBack );
                base.OnClick(e);
        }

        void CallBack()
        {
                this.Enabled = true;
        }
}

«RunAsynchronousMethod» может создать новый «поток» или использовать «ThreadPool.QueueUserWorkItem)».

EDIT:

public class SingleClickButton : Button {
        protected override void OnClick(EventArgs e) {
                this.Enabled = false;
                RunAsynchronousMethod( CallBack );
                base.OnClick(e);
        }

        void CallBack() {
                this.Enabled = true;
        }

        void RunAsynchronousMethod( Action callBack ) {
                // there you can use ThreadPool or Thread
                ThreadPool.QueueUserWorkItem( this.Worker, callBack );
        }

        void Worker( object callBack ) {
                try {
                    // some operations
                }
                finally {
                    // after operations was proceeded, the callback function will
                    // be called
                    ((Action)callBack)();
                }
        }
}
0 голосов
/ 27 апреля 2017

Проблема с включением и отключением кнопки состоит в том, что, если то, что у вас есть в событии щелчка, выполняется так быстро, что кнопка включается до второго щелчка действия двойного щелчка (некоторые пользователи не понимают, что это займет всего 1 нажмите) так вот мое решение.

private const int waittime = 2;
private DateTime clickTime = DateTime.Now;

private void cmd_TimeStamp_Click(object sender, EventArgs e)
{
  if ((DateTime.Now - clickTime).Seconds < waittime)
    return;
  else
    clickTime = DateTime.Now;
  try
  {
    cmd_TimeStamp.Enabled = false;
    //Do some stuff in here
  }
  catch (Exception ex)
  {
    //Show error if any
    MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  }
  finally
  {
    cmd_TimeStamp.Enabled = true;
  }
}
0 голосов
/ 09 октября 2014

Сначала я реализовал ответ @TcKs, который мне очень помог, но «серая кнопка» вызвала у меня некоторые проблемы. (некоторые пользователи думали, что в системе возникла проблема) Поэтому я делаю небольшое изменение, чтобы игнорировать только последующие клики.

bool ignoreClick = false;
protected override void OnClick(EventArgs e)
{
        // Prevent DoubleClick
        if (ignoreClick) return;
        ignoreClick = true;
        ThreadPool.QueueUserWorkItem(this.Worker);
        base.OnClick(e);
}
void Worker(object obj)
{
        try
        {
            Thread.Sleep(300);                
         }
         catch { }
         ignoreClick = false;
}
0 голосов
/ 06 марта 2014

Возможно, отключить кнопку, пока обработка не будет завершена?

0 голосов
/ 09 июня 2009

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

    private void btnPrintReport_Click(object sender, EventArgs e)
    {
        btnPrintReport.Enabled = false;
        timerEnablePrint.Enabled = true;
        BackgroundProcess.Add("Printing", new WaitCallback(generateReport), null);
    }


    private void timerEnablePrint_Tick(object sender, EventArgs e)
    {
        btnPrintReport.Enabled = true;
        timerEnablePrint.Enabled = false;
    }

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

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