Given that you have a control that fires a command:
Is there a way to prevent the command from being fired
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 )
Wrap the code in a try-catch-finally or try-finally block. The finally statement will always be called regardless of any error occurring in the try.
Example
private Cursor _CursorType;
// Property to set and get the cursor type
public Cursor CursorType
{
get {return _CursorType; }
set
{
_CursorType = value;
OnPropertyChanged("CursorType");
}
}
private void ExecutedMethodOnButtonPress()
{
try
{
CursorType = Cursors.Wait;
// Run all other code here
}
finally
{
CursorType = Cursors.Arrow;
}
}
NOTE: the CursorType is a property that the UserControl or Window is bound to
<Window
Cursor = {Binding Path=CursorType}>
If your control derives from System.Windows.Forms.Control, you can use the double click event.
If it doesn't derive from System.Windows.Forms.Control, then wire up mousedown instead and confirm the click count == 2 :
private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
//Do stuff
}
}
You could set a flag
bool boolClicked = false;
button_OnClick
{
if(!boolClicked)
{
boolClicked = true;
//do something
boolClicked = false;
}
}
You'd think that it would be as simple as using a Command
and making CanExecute()
return false while the command is running. You would be wrong. Even if you raise CanExecuteChanged
explicitly:
public class TestCommand : ICommand
{
public void Execute(object parameter)
{
_CanExecute = false;
OnCanExecuteChanged();
Thread.Sleep(1000);
Console.WriteLine("Executed TestCommand.");
_CanExecute = true;
OnCanExecuteChanged();
}
private bool _CanExecute = true;
public bool CanExecute(object parameter)
{
return _CanExecute;
}
private void OnCanExecuteChanged()
{
EventHandler h = CanExecuteChanged;
if (h != null)
{
h(this, EventArgs.Empty);
}
}
public event EventHandler CanExecuteChanged;
}
I suspect that if this command had a reference to the window's Dispatcher
, and used Invoke
when it called OnCanExecuteChanged
, it would work.
I can think of a couple of ways to solve this problem. One's JMarsch's approach: simply track when Execute
is called, and bail out without doing anything if it was called in the last few hundred milliseconds.
A more robust way might be to have the Execute
method start a BackgroundWorker
to do the actual processing, have CanExecute
return (!BackgroundWorker.IsBusy)
, and raise CanExecuteChanged
in when the task is complete. The button should requery CanExecute()
as soon as Execute()
returns, which it'll do instantly.
I had the same issue and this worked for me:
<Button>
<Button.InputBindings>
<MouseBinding Gesture="LeftClick" Command="New" />
</Button.InputBindings>
</Button>