robburke.NET
© 2010 Robert Burke
All Rights Reserved.

I had been merrily using WPF’s built-in support for the Command Pattern for ages (see Commanding Overview, MSDN Docs, and article on implementing the command pattern in WPF, Jeff Druyt)… when suddenly it occured to me that I had no idea what triggered WPF to determine whether or not a command can be executed.

Let me explain by reduction to an absurd example:

Say I have a command that can only execute when

DateTime.Now.Second % 2 == 0.

I construct this command by home-brewing a static RoutedCommand instance:

public static class Commands

{

public static RoutedCommand MyCommand { get { return m_MyCommand; } }

private static RoutedCommand m_MyCommand = new RoutedCommand

(

“Execute My Command”,

typeof(Commands),

new InputGestureCollection()

{

new KeyGesture(Key.C, ModifierKeys.Alt)

}

);

}

And then I add a Command Binding for that command to my Window, and assign the command to a Button:

<Window x:Class=”TestCommands.Window1″…>
<Window.CommandBindings>
<CommandBinding
Command=”{x:Static local:Commands.MyCommand}”
Executed=”MyCommandExecuted”
CanExecute=”MyCommandCanExecute”
/>
</Window.CommandBindings>

<Button Width=”200″ Height=”200″
Command=”{x:Static local:Commands.MyCommand}”
Content=”{Binding Path=IsEnabled}”
/>

</Window>

By nature of WPF’s awesomeness and WPF Commanding in general, the above Button’s IsEnabled property should automatically be set to true or false based on whether or not the command can or can’t be executed.

Speaking of which, let’s set up my Command’s absurd logic in the CodeBehind by implementing its Execute and CanExecute event handlers:

private void MyCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)

{

DateTime now = DateTime.Now;

if (CanExecuteOutput != null)

{

CanExecuteOutput.Text = “MyCommand CanExecute determined at “ +

now.ToLongTimeString() + ” (and “ + now.Millisecond + “ms)”;

}

e.CanExecute = DateTime.Now.Second % 2 == 0;

}

private void MyCommandExecuted(object sender, ExecutedRoutedEventArgs e)

{

TextOutput.Text = “MyCommand executed at “ + DateTime.Now.ToLongTimeString();

}

So, my example is absurd but I bet you see my point by now: WPF is meant to automatically set the IsEnabled Property on that button to true or false, based on the results of the CanExecute method. But in this case, the results of CanExecute are a function only of time, and thus change repeatedly and independently of “obvious” application events. So… how does the Commanding system know when to query CanExecute and consequently enable/disable the button once a second?

In this case, without further intervention, it doesn’t. It seems that when events are raised on the Window (a mouse button click, etc.), CanExecute is re-evaluated. (I don’t know the details and wish I did.)  But, without further programmatic or user intervention, the button will not automatically change its IsEnabled state once a second.

This led me back to the MSDN docs, where I discovered the aptly-named InvalidateRequerySuggested event. To coerce – er, suggest – that WPF should query CanExecute, I set up the following DispatcherTimer:

m_DispatcherTimer = new DispatcherTimer()

{

Interval = TimeSpan.FromSeconds(0.25),

IsEnabled = true

};

m_DispatcherTimer.Tick += delegate

{

CommandManager.InvalidateRequerySuggested();

};

Now, the IsEnabled property of the Button blinks on and off as the Command’s ability to be executed changes with the passing seconds.

Only then did I discover there’s an MSDN Docs sample called “Disable Command Source Via Dispatcher Timer Sample” which is remarkably similar.

There you have it. Now go forth and command WPF’s Commanding. I’m sure you can all execute on that request <g>

P.S. Code for this sample is here.

P.P.S. What are folks using for pasting XAML and C# code into their blogs? This entry is looking a little rough…

Possibly Related Articles (possibly not):

14 Responses to “WPF Commanding – When do Commands re-evaluate their CanExecute method?”

  1. Dmitry 22nd May 2008 @ 9:48 am

    Tht’s great investigation! It was very helpfull for me. Thanks!

  2. Rhywun 31st Aug 2008 @ 12:39 pm

    Me too – thanks!

  3. igor 28th Oct 2008 @ 11:24 am

    thanks, very helpfull

  4. Daniel 7th Nov 2008 @ 6:55 am

    This doesn’t work when used with a built in command like ApplicationCommands.Print, any idea why?

    Kind regards,

    Daniel

  5. David Smith 1st Dec 2008 @ 4:34 pm

    By default CanExecute is requeried on focus change for RoutedCommand (RoutedUICommand inherits from RoutedCommand as well).

  6. Geert van Horrik 23rd Jan 2009 @ 8:42 am

    Just what I was looking for! Thank you!

  7. Amatzia 18th Feb 2009 @ 10:18 am

    You just made my day!

    Thanks a lot

    :-)

  8. Oskar 25th May 2009 @ 5:04 am

    InvalidateRequerySuggested() was just what I was looking for, thanks for sharing!

  9. [...] http://robburke.net/2008/04/23/wpf-command-pattern-when-does-it-query-canexecute/ Thursday, 28 May 2009 05:47:02 UTC      Comments [0]    |  Trackback [...]

  10. Kanary 2nd Feb 2010 @ 6:53 pm

    Excellent!!! Thank you!

  11. Miky 22nd Feb 2010 @ 6:59 pm

    Many thanks :)
    Thank god google put you on first page ;)
    Saved me a lot of digging

  12. tim 3rd Jun 2010 @ 2:59 am

    Lifesaver.

  13. Sudarsan Srinivasan 14th Jul 2010 @ 4:46 am

    Thanks a lot

  14. mikki 1st Aug 2010 @ 12:27 am

    thanks dude, exactly what I needed. Seems like the whole command architecture is really only worth it at a certain level of complexity of your application. otherwise you’d do the same thing old school with less lines of code.

Trackback URI | Comments RSS

Leave a Comment