2017-09-28 5 views
1

Hintergrund

Während bei Josh Smith Artikel über CommandGroup suchen, bemerkte ich, dass eine Reihe von Kommentaren im Internet über gibt es, wie ICommand.CanExecuteChanged zu implementieren.Wie soll 'ICommand.CanExecuteChanged' implementiert werden?

Eine ähnliche Frage here auf Stackoverflow wurde geschrieben, aber

  1. Ich fühle mich nicht wie es eine klare Antwort, und
  2. gibt es nicht genug Platz in einem Kommentar der Lage sein, weitere hinzufügen Kontext.

Zum Vergleich:

  1. Josh Smith ursprüngliche article über CommandGroup verwendet ein einfaches .NET Ereignis
  2. Josh Smith RelayCommand ein verwendet CommandManagerimplementation von CanExecuteChanged
  3. Microsofts eigenen RoutedCommand verwendet ein CommandManagerimplementation von CanExecuteChanged
  4. Microsofts eigene PRISM-Bibliothek (Version: 6) uses auch ein einfaches .NET-Ereignis (frühere Versionen verwendeten schwacher Verweis)

Meine Frage

Ich bin relativ neu in WPF, und ich würde gerne wissen, wie Das Ereignis CanExecuteChanged sollte in Josh Smiths CommandGroup implementiert werden, um unerwartete Verhaltensweisen oder Speicherlecks zu vermeiden?

Weiterführende Literatur

Josh Smith: Aggregating WPF Commands with CommandGroup

Josh Smith: WPF apps with the MVVM design pattern

StackOverflow: Is Josh Smith's implementation of the RelayCommand flawed?

StackOverflow: comment about CanExecuteChanged

Microsoft: RoutedCommand

PRISM 6: DelegateCommandBase

Antwort

0

Sagen wir, Sie binden einen Befehl an eine Schaltfläche. Wenn die Schaltfläche gerendert wird, ruft sie CanExecute() auf und wird basierend auf dem Ergebnis entweder als Enabled oder Disabled dargestellt. WPF ruft CanExecute() automatisch auf, wenn "es entscheidet" aber Sie sollten dieses Verhalten nie weiterleiten.

Wenn Sie also ICommand implementieren, deklarieren Sie eine Methode wie UpdateCommand(), wodurch das fragliche Ereignis ausgelöst wird, wenn Sie sich entscheiden. Wenn Sie zum Beispiel auf eine Schaltfläche klicken, wird eine langsame Operation gestartet, die nach dem Beenden der vorherigen erneut ausgelöst werden sollte. Sie sollten das Ereignis zweimal auslösen - einmal vor dem Start und einmal nach Abschluss der Operation.

Es gibt keine "den besten Weg, um ICommand.CanExecuteChanged zu implementieren".Wahrscheinlich war das ein Teil der Gründe, eine Standard-Implementierung von ICommand nicht mit dem Framework zu versenden. Die meisten MVVM-Framework, bieten Standard-Implementierungen: RelayCommand, ActionCommand, ParameterCommand, AsyncCommand, etc. Sie machen nur die Dinge einfacher - übergeben Sie einen Delegierten und Sie sind bereit zu gehen. Der Artikel von Josh Smith löst ein anderes Problem, eine saubere Möglichkeit, mehrfach geroutete Befehle in XAML zu verketten.

Allgemein gilt:

  1. Verwenden ICommand mit MVVM
  2. Verwenden RoutedCommand, wenn Sie wiederverwendbare Steuerelemente erstellen und Sie den Befehl zu sprudeln die visuelle Struktur, so dass die interessierten vorfahren kann es
  3. Griff Sie können das Dekorator-Designmuster verwenden und alle Befehle, , so dekorieren, dass Sie eine höhere Funktionalitätsebene hinzufügen können, wie Befehle, die nur für berechtigte Benutzer aktiv sind, alle Befehle auf einmal deaktivieren usw. Stellen Sie sicher, dass der Dekorator für die Die tatsächlichen Befehle CanExecuteChanged und re-f Ire die Veranstaltung in ihrem Namen
+0

Vielen Dank für Ihr Feedback. Ich höre was du sagst, aber es scheint nicht so geradlinig zu sein. Nehmen wir zum Beispiel den Artikel [Ist Josh Smiths Implementierung des RelayCommand fehlerhaft?] (Https://stackoverflow.com/q/2281566/949681). Dieser Thread enthält Kommentare von einigen sehr erfahrenen Entwicklern, die zu dem Thema hin und her gegangen sind. Gedanken? – Pressacco

Verwandte Themen