2010-12-01 2 views
4

Ich verwende das MVVM-Muster auf ein Projekt. Ich habe ein UserControl, das eine Schaltfläche hat, die an einen Befehl gebunden ist, der von dem ViewModel verfügbar gemacht wird. Da die Schaltfläche sichtbar ist, ruft sie fortlaufend die CanExecute-Methode der Schaltfläche auf. Irgendetwas sagt mir, dass das eine Leistungsproblem trägt, aber ich bin mir nicht sicher. Ist das das erwartete Verhalten? Oder gibt es eine bessere Möglichkeit, einen Button an einen Befehl zu binden?Leistungseinbuße von kontinuierlichen CanExecute-Aufrufen in Befehl

Vielen Dank.

+0

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

+0

Welche Art von ICommand verwenden Sie? Verschiedene Implementierungen können sich in Bezug auf CanExecute-Updates sehr unterschiedlich verhalten. –

+0

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. –

Antwort

1

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.

+0

Wo ist die Lösung? – qakmak

+0

Um was? Wenn Sie nicht möchten, dass Ihre Befehle vom RequerySuggested-Ereignis abgefragt werden, verwenden Sie nicht RelayCommand. –

+0

Um das Leistungsproblem zu beheben. Ich dachte, du versuchst es zu beheben ...... – qakmak

Verwandte Themen