WPF - How to force a Command to re-evaluate 'CanExecute' via its CommandBindings
I couldnt use CommandManager.InvalidateRequerySuggested();
because I was getting performance hit.
I have used MVVM Helper's Delegating command, which looks like below (i have tweaked it a bit for our req). you have to call command.RaiseCanExecuteChanged()
from VM
public event EventHandler CanExecuteChanged
{
add
{
_internalCanExecuteChanged += value;
CommandManager.RequerySuggested += value;
}
remove
{
_internalCanExecuteChanged -= value;
CommandManager.RequerySuggested -= value;
}
}
/// <summary>
/// This method can be used to raise the CanExecuteChanged handler.
/// This will force WPF to re-query the status of this command directly.
/// </summary>
public void RaiseCanExecuteChanged()
{
if (canExecute != null)
OnCanExecuteChanged();
}
/// <summary>
/// This method is used to walk the delegate chain and well WPF that
/// our command execution status has changed.
/// </summary>
protected virtual void OnCanExecuteChanged()
{
EventHandler eCanExecuteChanged = _internalCanExecuteChanged;
if (eCanExecuteChanged != null)
eCanExecuteChanged(this, EventArgs.Empty);
}
Not the prettiest in the book, but you can use the CommandManager to invalidate all commandbinding:
CommandManager.InvalidateRequerySuggested();
See more info on MSDN
For anyone who comes across this later; If you happen to be using MVVM and Prism, then Prism's DelegateCommand
implementation of ICommand
provides a .RaiseCanExecuteChanged()
method to do this.