Sorry, ich habe herausgefunden, was passiert ist. Dies ist die Implementierung von RelayCommand.
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}
Ich hatte fälschlicherweise angenommen, dass das System alle Befehle automatisch erneut abfragt. Was es tatsächlich tut, ist das Hooten des CanExecuteChanged-Ereignisses jedes Befehls, und RelayCommand verknüpft sein CanExecuteChanged-Ereignis im Grunde mit dem RequerySuggested-Ereignis des CommandManagers, so dass jedes Mal, wenn das System eine Requery "vorschlägt", alle meine RelayCommands erneut abgefragt werden.
Vielen Dank.
Warum ruft die Schaltfläche "CanExecute" kontinuierlich auf? Dies geschieht standardmäßig nicht und sollte nur dann ausgeführt werden, wenn 'ICommand.CanExecuteChanged' ausgelöst wurde. – Jens
Welche Art von ICommand verwenden Sie? Verschiedene Implementierungen können sich in Bezug auf CanExecute-Updates sehr unterschiedlich verhalten. –
Ich benutze nur die normale ICommand-Schnittstelle. Eigentlich die RelayCommand-Klasse, die nichts Besonderes ist, außer dass sie Delegate-Injection verwendet, um meine Methoden anzugeben. –