WPF Commanding – When do Commands re-evaluate their CanExecute method?
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…
Mike Holmes Makes it Right
Mike Holmes is well on his way to being my new idol.
If you’re reading this from Canada, you already know Mike: the contractor who arrives at the scene of botched renovation jobs and works his magic.
So why do I love this guy?
1. He seems to know everything there is to know about construction. We’re talking deep knowledge of every subdomain of home renovation. It’s knowledge (and wisdom) that only comes from years of experience.
2. His mantra is “Make it right [the first time].” Fellow software developers, you know this story, right?
3. The concept for his show is an entrepreneur’s dream:
Take an existing idea: shows about home renovation, which are a dime a dozen.
Make a clever addition: start on a site where the contractors screwed up.
Suddenly, look at this innovative format you’ve got:
a show with conflict (in the dramatic sense only – Mike has a policy of not naming and shaming)
episodic story arcs that are much more engaging
(most importantly) a useful tweak to the format that gives Mike and his crews ample opportunity to relay relevant information about a reno to the audience, without relying on awkward asides.
More information: Check out the Holmes on Homes Website.
Continue ReadingMake your own WPF Custom BitmapEffects
Custom WPF Bitmap Effects, authored in a Managed C++ assembly, complete with sample project to help you roll your own. It works, complete with live preview, in Expression Blend. Done by a guy called Rob who has a blog called Run To The Hills. ‘Nuff said.
p.s. My suggestion to Rob: turn this into a Visual Studio Project Starter Kit. The process is relatively painless and this would be very useful as a Starter Kit!
Update 15 Apr: Although this is a truly valiant attempt, I think at this point you need to heed the caveat Rob adds in his blog: “Although bitmap effects are very costly in terms of rendering in WPF since they force the whole stack to render your control hierarchy in software – the effects aren’t really all that slow and although the advice to avoid bitmap effects if possible still stands, I find judicious use of them acceptable, especially if used on something that is static.”
Continue Reading“Mate, this is the Future”
I’m currently consulting independently for an incredibly cool team of developers and designers. The process has been a joy, both for me and for my clients. In part, it has shown me that Expression Blend (2.5) has matured to the point where it delivers on the promise of dramatically improving the developer-designer workflow.
I had the good fortune of working with my clients’ lead designer about 5 years ago, on a Managed DirectX project that proceeded very much like “tweak, compile, run.” The current WPF project is, instead, very much “nudge, nudge, nudge.”
Their lead designer, upon seeing his artwork and user interface come alive in Blend, reflected back on the not-quite-as-good old days and said: “Mate, this is ‘the future’.”
How we collaborate
Even though he doesn’t always work with the main branch when adding new content, he routinely authors XAML content (including Storyboards) in side projects. We developers then just grab and paste it into the application. And then the designer “nudges” the content some more.
This “side Project” technique helps us transfer from designer to developer the burden of enforcing a coding guideline like the Stovell Conventions, and lets designers focus instead on being creative with Blend. (Relevant aside: I really like Paul’s Guidelines, particularly regarding Resource organization).
It’s gone so well that next week I’m introducing the lads to the nerd+art snippets so they can increase their superpowers. (The first time their lead designer wrote a C# event handler himself, he took a screen shot of the C# code and sent it to the rest of the developers just to show off) :)
I have all the Artistic Ability of a Slug
I mentioned that this experience has also been a joy for me as a developer. I feel like I’ve put a creative framework into the hands of someone who can make it work wonders. And it cost me a lot less ($0) than it would have cost me to buy my musical little sister a Baby Grand…
Continue Reading