A solution might be to implement a simpler version of the RelayCommand
class that simply stores the event handlers itself and exposes a public method to fire them when appropriate:
public class RelayCommand : ICommand
{
public event EventHandler CanExecuteChanged;
// Further ICommand implementation omitted...
public void Invalidate()
{
var handler = this.CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
You then call the following in your viewModel to re-evaluate the command:
fooCommand.Invalidate();
Of course, this leaves you with the opposite problem that you now have to manually re-evaluate all commands...
Edit
To elaborate on the comments, most RelayCommand
's implement the CanExecuteChanged
event like this:
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
When the UI subscribes to the command's CanExecuteChanged
event it is actually being indirectly subscribed to the CommandManager.RequerySuggested
event which is why your CanExecute
method is being called every time the CommandManager
suggest a re-query.
The simpler RelayCommand
I have suggested avoids this problem by not subscribing to the CommandManager.RequerySuggested
event.