Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent double-click from double firing a command

Given that you have a control that fires a command:

<Button Command="New"/>

Is there a way to prevent the command from being fired twice if the user double clicks on the command?

EDIT: What is significant in this case is that I am using the Commanding model in WPF.

It appears that whenever the button is pressed, the command is executed. I do not see any way of preventing this besides disabling or hiding the button.

like image 370
Josh G Avatar asked May 08 '09 19:05

Josh G


4 Answers

It is possible that any event handler that contains code that requires a significant process time, can result in a delay to the disabling of the button at question; regardless to where the disabling line of code is called within the handler.

Try the proofs below and you will see that disable/enable has no correlation to the registration of events. The button click event is still registered and is still handled.

Proof by Contradiction 1

private int _count = 0;
    
private void btnStart_Click(object sender, EventArgs e)
{
    btnStart.Enabled = false;
    
    _count++;
    label1.Text = _count.ToString();

    while (_count < 10)
    {            
        btnStart_Click(sender, e);            
    }           

    btnStart.Enabled = true;
}

Proof by Contradition 2

private void form1_load(object sender, EventArgs e)
{
    btnTest.Enabled = false;
}

private void btnStart_Click(object sender, EventArgs e)
{
    btnTest.Enabled = false;
    btnTest_click(sender, e);
    btnTest_click(sender, e);
    btnTest_click(sender, e);
    btnTest.Enabled = true;
}

private int _count = 0;

private void btnTest_click(object sender, EventArgs e)
{
    _count++;
    label1.Text = _count.ToString();
}
like image 124
JDennis Avatar answered Oct 15 '22 08:10

JDennis


Simple & Effective for blocking double, triple, and quadruple clicks

<Button PreviewMouseDown="Button_PreviewMouseDown"/>

private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.ClickCount >= 2)
    {
        e.Handled = true;
    }
}
like image 35
Jon Dosmann Avatar answered Oct 15 '22 09:10

Jon Dosmann


I had the same issue and this worked for me:

<Button>
    <Button.InputBindings>
            <MouseBinding Gesture="LeftClick" Command="New" />
    </Button.InputBindings>
</Button>
like image 23
Olek Avatar answered Oct 15 '22 10:10

Olek


Assuming that WPF Commanding doesn't give you enough control to mess with the click handler, could you put some code in the command handler that remembers the last time the command was executed and exits if it is requested within a given time period? (code example below)

The idea is that if it's a double-click, you'll receive the event twice within milliseconds, so ignore the second event.

Something like: (inside of the Command)


// warning:  I haven't tried compiling this, but it should be pretty close
DateTime LastInvoked = DateTime.MinDate;
Timespan InvokeDelay = Timespan.FromMilliseconds(100);
{
  if(DateTime.Now - LastInvoked <= InvokeDelay)
     return;

  // do your work
}

(note: if it were just a plain old click handler, I'd say follow this advice: http://blogs.msdn.com/oldnewthing/archive/2009/04/29/9574643.aspx )

like image 29
JMarsch Avatar answered Oct 15 '22 10:10

JMarsch