views:

49

answers:

2

I have a button on a toolbar that has its command set to "MyControl.Print" (for example). In the control the command is added to the command bindings including both the Execute and CanExecute.

The control is within a window with other controls docked appropriately. I am finding that for the Print button to be enabled I have to "select" MyControl first which does not provide a good user experience and indeed causes various "bugs" being raised and lots of confusion.

Is there a way that I can ensure that the button is enabled whether or not the control has been "selected"?

A: 

Since the CanExecute doesn't fire, I think you might be looking at the major downside to RoutedCommands - the way they tunnel and bubble can leave a highly composed interface unable to have commands arrive anywhere useful. For this reason we ended up moving to DelegateCommands from (I think) the Microsoft CAG. Not any of the other stuff, just the commands. Works a lot better, and isn't tied in to the interface so tightly.

Oh, the other response raises a good point. I assumed you meant that to ever print, your MyControl needed to have keyboard focus. Is it only the first time and after that it works?

I recommend http://msdn.microsoft.com/en-us/library/ff921126(PandP.20).aspx as a pretty good starting point. You don't have to worry too much about the IActiveAware up front, since you're hoping for this command to be available all the time (or at least let its availablity be determined by CanExecute).

Chris Hagan
The CanExecute does not fire until I select/click on the control in the window, then it all functions as expected
David Ward
After initially receiving the focus, it works properly from then on
David Ward
Then yeah, CommandManager.InvalidateRequerySuggested sounds ok. It's a bit heavy though, and not recommended for (eg) raising on every keystroke: "In some situations, the CommandManager is unaware of a change in conditions that alters the ability of a command to execute. In these cases, you can force the CommandManager to raises the RequerySuggested event by calling the InvalidateRequerySuggested method, this will in turn cause the RoutedCommand to raise the CanExecuteChanged event. " (http://msdn.microsoft.com/en-us/library/system.windows.input.routedcommand.canexecutechanged.aspx)
Chris Hagan
Been off this for a couple of days...looking back the button is only enabled in the menu when the child control is selected. Do you know any good samples for using DelegateCommands? - I can only find simple examples that don't cover my "child control" scenario. This is really starting to cause me some pain so any help appreciated
David Ward
+1  A: 

CommandManager.InvalidateRequerySuggested will force the command manager to re-call all of your CanExecute methods and should disable the button. Perhaps call that onload?

David Kiff