During my first WPF project I noticed (like most people starting in WPF do) that DelegateCommand.CanExecute is called once and never refreshed. To force a refresh one must call RaiseCanExecuteChanged when the state of CanExecute has changed. That had a few smells about it and was cubersome, so when I stumbled across CommandManager.RequerySuggested I thought all my problems were solved.
From MSDN ”Occurs when the CommandManager detects conditions that might change the ability of a command to execute.”
All I did was create my own DelegateCommand and proxy the CanExecutedChanged event to the CommandManager.RequerySuggested event and every time WPF noticed something change it would force a refresh of my CanExecute methods. I even had the audacticity to call it BetterDelegateCommand!!
This didn’t cause too many problems on the project, as a general rule people know to keep the CanExecute logic quick and we had linear navigation in the application so there wouldn’t have been more than 10 commands bound at anyone point.
Things quickly change when you move to apps that have multiple windows/dialogs/plugins loaded and hundreds of commands can be bound. Spice that up with a developer adding CanExecute methods that do a little more than test the value of a variable and you get a significant slowdown which is very hard to debug.
Because there are times when using the RequerySuggested method is preferable Present.Commands provides the RequeryCommandDecorator and fluent method.
MyCommand = Command.Async(new SomeAction()) .ToCommand() .SuggestRequery();
For everything else there is the CanExecuteChangedDecorator and fluent command. It allows you to specify an Observable which it subscribes to, when a notification comes through the CanExecuteChanged event is fired. Using an Observable adds a powerful filtering and joing tool to define when the command ‘s state has changed.
MyCommand = Command.Async(new SomeAction()) .ToCommand() .CanExecuteChangedWhen(this.WhenPropertyChanges(x => x.SomeProperty));