Ist Josh Smiths Implementierung des RelayCommand fehlerhaft?
Betrachten Sie die ReferenzJosh Smiths Artikel WPF Apps With The Model-View-ViewModel Design Pattern, speziell die Beispielimplementierung von aRelayCommand
(In Abbildung 3). (Für diese Frage muss nicht der gesamte Artikel durchgelesen werden.)
Generell finde ich die Umsetzung hervorragend, habe aber eine Frage zur Delegation vonCanExecuteChanged
Abonnements für dieCommandManager
'sRequerySuggested
Veranstaltung. DasDokumentation fürRequerySuggested
Zustände:
Da dieses Ereignis statisch ist, wird der Handler nur als schwache Referenz verwendet. Objekte, die auf dieses Ereignis warten, sollten einen starken Verweis auf ihre Ereignisbehandlungsroutine behalten, um zu verhindern, dass das Ereignis durch Garbage-Collection erfasst wird. Dies kann erreicht werden, indem ein privates Feld vorhanden ist und der Handler als Wert vor oder nach dem Anhängen an dieses Ereignis zugewiesen wird.
Die Beispielimplementierung vonRelayCommand
verwaltet keine solchen für den abonnierten Handler:
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
Tritt hierdurch die schwache Referenz aufRelayCommand
's Client, erfordert, dass der Benutzer desRelayCommand
verstehen die Umsetzung vonCanExecuteChanged
und selbst eine Live-Referenz pflegen?Wenn ja, ist es sinnvoll, z. B. die Implementierung von zu modifizierenRelayCommand
so etwas wie das folgende zu sein, um die potenzielle vorzeitige GC der zu mildernCanExecuteChanged
Teilnehmer:
// This event never actually fires. It's purely lifetime mgm't.
private event EventHandler canExecChangedRef;
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
this.canExecChangedRef += value;
}
remove
{
this.canExecChangedRef -= value;
CommandManager.RequerySuggested -= value;
}
}