Можно ли избежать нескольких нажатий кнопок на Winform?

Предположим, у вас есть кнопка в форме, которая считает до 1000 в текстовом поле, а затем очищает его.

Если я быстро нажму кнопку пять раз (во время выполнения), обработчик события Click будет вызываться 5 раз, и я увижу, что счетчик равен 1000 пять раз.

Можно ли отключить другие клики по этой кнопке, пока засчитывается первый клик?

Примечание. Отключение кнопки в первом операторе обработчика кликов, а затем повторное включение в конце не работает. Кроме того, отмена подписки/подписка на событие клика (-=, за которым следует +=) не работает.

Вот пример для иллюстрации:

  private bool runningExclusiveProcess = false;

    private void button1_Click(object sender, EventArgs e)
    {
        this.button1.Click -= new System.EventHandler(this.button1_Click);

        if (!runningExclusiveProcess)
        {
            runningExclusiveProcess = true;
            button1.Enabled = false;


            textBox1.Clear();
            for (int i = 0; i < 1000; i++)
            {
                textBox1.AppendText(i + Environment.NewLine);
            }


                runningExclusiveProcess = false;
            button1.Enabled = true;
        }

        this.button1.Click += new System.EventHandler(this.button1_Click);
}

person tzup    schedule 06.08.2009    source источник
comment
Вы выполняете всю работу в потоке пользовательского интерфейса. Он всегда будет доходить до конца этого метода, прежде чем вы снова сможете нажать кнопку. Код, вероятно, требует гораздо меньше времени для запуска, чем вы думаете.   -  person xyz    schedule 06.08.2009
comment
Счет до 1000 уже не та задержка, которая была раньше. Ваш компьютер считает до 1000 между щелчками. (Несколько Sleep() или других более длительных вызовов функций покажут поведение, которое вы ожидаете)   -  person Brad Bruce    schedule 06.08.2009
comment
@tzup Вы правы в том, что клики ставятся в очередь, даже если поток пользовательского интерфейса заблокирован. Я этого не знал. Удалю свой ответ :)   -  person xyz    schedule 06.08.2009
comment
@Brad Bruce Идея состоит в том, чтобы избежать многократного вызова обработчика событий, если конечный пользователь быстро щелкает его несколько раз. Вы можете попробовать перевести поток в спящий режим на пару секунд, чтобы замедлить функцию, но он все равно будет выполняться столько раз, сколько вы нажали.   -  person tzup    schedule 06.08.2009


Ответы (3)


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

person Ray    schedule 06.08.2009

Фрагмент кода здесь:

открытый частичный класс Form1: Form { public int Count { get; задавать; }

    public Form1()
    {
        InitializeComponent();

        this.Count = 0;
    }

    private void GOBtn_Click(object sender, EventArgs e)
    {
        this.GOBtn.Enabled = false;

        this.Increment();

        this.GOBtn.Enabled = true;
    }

    public void Increment()
    {
        this.Count++;
        this.CountTxtBox.Text = this.Count.ToString();
        this.CountTxtBox.Refresh();

        Thread.Sleep(5000);  //long process

    }
}
person Dean    schedule 12.12.2013

private bool HasBeenClicked = false;

private void button1_Click(object sender, EventArgs e)
    {
       if( HasBeenClicked )
          Application.DoEvents();
       else {
          HasBeenClicked = true;
          // Perform some actions here...
          }
    }

Это должно сделать это. :о)

person jay_t55    schedule 16.08.2009