Bricht das Aufrufen von Model-Methoden in Code-Behind-Ereignissen die MVVM?

8

Ich frage mich, ob das das MVVM-Muster brechen würde und wenn ja, warum und warum ist es so schlimm?

WPF:

%Vor%

Hinterer Code:

%Vor%

Modell anzeigen:

%Vor%

IMHO, es hält den Code ziemlich einfach, das Ansichtsmodell ist immer noch agnostisch bezüglich der Ansicht und des Codes dahinter und eine Änderung der Ansicht hat keinen Einfluss auf die Geschäftslogik.

Es scheint mir einfacher und klarer als Commands oder CallMethodAction .

Ich will nicht die Art von Antwort "es ist nicht wie es gemacht werden soll". Ich brauche einen sachlichen und logischen Grund, warum dies zu Wartungs- oder Verständnisproblemen führen könnte.

    
Sébastien 20.10.2016, 17:24
quelle

2 Antworten

10

Nein, das ist vollkommen in Ordnung .

Es ist der Job der View, um Benutzereingaben zu handhaben und mit dem ViewModel zu interagieren. Ein Button-Click-Event-Handler, der als Antwort eine Methode des ViewModels aufruft, fällt recht sauber in diese Rolle.

Was Sie gepostet haben, ist sauber, lesbar, effizient, wartbar und vollständig im Sinne des MVVM-Entwurfsmusters.

Nun, in einem allgemeineren Sinn, was Sie wirklich fragen wollen, ist: "Warum wählen Sie ICommands, vs Event Handler für MVVM?" Nun, Sie würden sicherlich nicht be | the | zuerst .

    
BTownTKD 20.10.2016, 17:33
quelle
2

Nein, es bricht MVVM nicht, solange Sie keine Logik einführen, die geeigneter in das View-Modell gehört.

Es hat das Potenzial, die Übersichtlichkeit zu reduzieren, IMO, weil es die Ansicht in XAML- und c # -Dateien unterbricht, die eng miteinander verbunden sind und wo Sie nicht alles an einem Ort sehen können. Ich finde es einfacher, Null-Code zurück zu haben, weil es weniger Kontextwechsel bedeutet, wenn man an der Ansicht arbeitet.

Es kann auch die Arbeit in einer Umgebung erschweren, in der Ihr UI-Designer kein C # -Programmierer ist, da dann zwei verschiedene Personen die eng gekoppelten Dateien verwalten.

Bearbeiten

Hier ist ein Beispiel dafür, was ich meine. Dies ist von einem Wochenendprojekt, das ich gemacht habe, um Minesweeper in WPF für Spaß und Erfahrung zu implementieren. Eine meiner größten WPF-Herausforderungen war die Mauseingabe. Für alle, die bisher keine Zeit mit dem Spiel verschwendet haben, zeigt die linke Maustaste eine Zelle, die rechte Maustaste schaltet eine Flagge auf der Zelle und die mittlere Maustaste zeigt (bedingt) benachbarte Zellen an.

Ich habe zunächst damit begonnen, die EventTrigger von System.Windows.Interactivity zusammen mit InvokeCommandAction zu verwenden, um Ereignisse Befehlen zuzuordnen. Diese Art funktionierte für die rechte Maustaste (war kein echtes Klickereignis, sondern eine MouseRightButtonUp), aber es würde überhaupt nicht für die mittlere Maustaste funktionieren, die keine spezifischen Aktionen hatte, nur das generische MouseDown / MouseUp. Ich habe kurz die Prism-Variante von InvokeCommandAction betrachtet, die den MouseButtonEventArgs an seinen Handler übergeben kann, aber das hat das MVVM-Konzept sehr zerstört und ich habe es schnell verworfen.

Ich mochte die Idee, Event-Handler direkt in den Code-Behind zu setzen, nicht, weil das die Aktion (den Mausklick) und die Antwort (die Zellen usw.) eng miteinander verknüpft. Es war auch keine sehr wiederverwendbare Lösung - jedes Mal, wenn ich einen mittleren Klick handhaben wollte, würde ich kopieren, einfügen und bearbeiten.

Worauf ich mich eingelassen habe, war folgendes:

%Vor%

In diesem Fall gibt es keinen Code im Code dahinter. Ich habe es in eine MouseTrigger -Klasse verschoben, die ich erstellt habe und die von System.Windows.Interactivity.TriggerBase erbt, das, obwohl es sich um Code der Ansichtsschicht handelt, nicht Teil einer bestimmten Ansicht ist, sondern eine Klasse, die jede Ansicht verwenden kann. Dieser Handler-Code ist so agnostisch wie möglich, um zu wissen, an welche Art von Element er angehängt ist - alles, was von UIElement abgeleitet wird, funktioniert.

Indem ich diesen Ansatz nutzte, bekam ich zwei wichtige Dinge in den Event-Handlern auf dem Code-Behind:

  1. Zwischen dem Ereignis und der Aktion besteht eine lockere Verbindung. Wenn ein UXD auf der Benutzeroberfläche ausgeführt wurde, konnte durch Ändern einer XAML-Zeile geändert werden, welcher Maustaste der Befehl zugeordnet war. Beispielsweise ist das Tauschen der rechten und mittleren Maustaste trivial und erfordert keine .cs-Änderungen.
  2. Es ist auf jedem UIElement wiederverwendbar und nicht an ein bestimmtes Element gebunden. Ich kann das jederzeit abrufen, wenn ich diese Art von Problemen in Zukunft lösen muss.

Der Hauptnachteil ist, dass es anfänglich mehr Arbeit zu schaffen gab. Meine MouseTrigger-Klasse ist komplexer als die Event-Handler selbst (hauptsächlich, um die Abhängigkeitseigenschaften und deren Änderungen richtig zu behandeln). XAML kann auch für etwas ziemlich einfach sein, das einfach erscheint.

    
PMV 20.10.2016 17:35
quelle

Tags und Links