Sollte ViewModel oder View in MVVM für das Erstellen neuer Ansichten verantwortlich sein?

11

In meiner WPF-Anwendung möchte ich eine neue Ansicht erstellen. Wo soll ich das tun - in ViewModel oder Model ?

Die Anwendung ist ein (vorerst sehr einfaches) formularähnliches Tool mit einem Fenster und einer einzigen Schaltfläche "Senden". Wenn eines der Kontrollkästchen aktiviert ist, sollte ein neues Fenster mit demselben ViewModel angezeigt werden, in dem der Benutzer nach zusätzlichen Details gefragt wird. Betrachten wir für die Zwecke dieser Frage nur den neuen Fensteransatz, ohne andere Ansätze wie das gezeigte / ausgeblendete Panel zu berücksichtigen.

Im Idealfall sollte in View kein Code vorhanden sein. Da View keine Logik enthält, müsste VM zunächst prüfen, ob eine neue Ansicht erstellt werden muss, und - wenn dies der Fall ist - diese Verantwortung wieder an View übertragen, was zu einem Aufblähen des Codes führt.

Andererseits verstößt das Erstellen einer neuen Ansicht in ViewModel gegen das Prinzip, dass ViewModel nichts über View wissen sollte.

Ist es also besser, neue Ansichten in View oder ViewModel zu erstellen?

Mac70
quelle
1
Ich verstehe deine Frage nicht wirklich. Was bedeutet "In View oder ViewModel"? ViewModels erstellen keine Ansichten, und Ansichten erstellen sich sicherlich nicht selbst.
Robert Harvey
1
Ich meine, welche dieser Ebenen für die Erstellung neuer Ansichten verantwortlich sein sollte - das Signal dafür muss von irgendwoher kommen, wenn eine Aktion stattfindet. Ich habe das Modell vollständig von dieser Frage ausgeschlossen, da es überhaupt nichts über das Frontend wissen sollte.
Mac70
Vielleicht verstehe ich Ihre Frage nicht richtig, beide sollten Ihre Ansicht nicht beeinträchtigen. Wenn Sie eine neue Ansicht in Ihrem viewModel erstellen möchten, gibt es einen Grund, warum Sie in xaml keine Frames verwenden, um den Fensterinhalt mit einer Bindung an Ihr aktuelles viewModel zu ändern?
Siobhan

Antworten:

8

Ich verwende die Abhängigkeitsinjektion und eine IViewFactoryin das Ansichtsmodell injizierte, um beide Einschränkungen zu berücksichtigen.

Ein ProductViewModel(zum Beispiel) Aufruf this.viewFactory.Show("Details", this), ProductDetailsViewmit sich selbst als zu öffnen ProductViewModel. Es könnte auch eine Ansicht basierend auf einem anderen Ansichtsmodell mit öffnen this.viewFactory.Show<ClientViewModel>().

Die Implementierung (es gibt tatsächlich mehrere für WinForms, einfaches Wpf-Windows, eine Wpf-Shell mit Registerkarten, ...) basiert auf einer StructureMapKonvention. Die Ansichten bestimmen ihr Ansichtsmodell über eine IView<ProductViewModel>Schnittstelle.

Das Ansichtsmodell weiß also nichts über die Ansicht außer ihrer Rolle (Standardansicht, Detailansicht, ...), und die Ansicht enthält keinen Code zum Erstellen einer anderen Ansicht. Außerdem befinden sich die Ansichtsmodelle in einer separaten Assembly, die auf keine Wpf-Assembly verweist.

Philippe
quelle
7

Theoretische Antwort

Wenn Sie eine haben ViewModel, sind Aktionen mit kosmetischen Effekten (z. B. Hervorheben eines Elements beim Mouseover) die Aufgabe von View, während Aktionen mit "echten" Effekten (z. B. das Laichen eines neuen Fensters) die Aufgabe von sind ViewModel.

Das Erstellen eines neuen Fensters ist daher eine Aufgabe für die ViewModel. Weder die Ansicht noch die ViewModelsollten wissen, wie genau ein Fenster erstellt werden soll. Dies gehört nicht zu ihren Verantwortlichkeiten und gehört zu einer anderen Klasse.

Sie könnten argumentieren, dass das Erstellen eines neuen Fensters eine Aufgabe für die ist View. Obwohl ich nicht zustimmen würde, ist eine solche Debatte wenig wertvoll, da es in der Praxis nicht das Ende der Welt ist, wenn Sie diesen Code in den Code einfügen View, und es auch nicht viel Arbeit ist, ihn zu ViewModeleinem späteren Zeitpunkt auf den zu verschieben . Der wichtige Teil ist, dass die Logik für die Erstellung eines neuen Fensters in einer unabhängigen Klasse enthalten ist, normalerweise einer Art WindowFactory. Der Punkt von MVVM, MVP, MVC usw. ist, dass Sie Klassen mit wenigen und genau definierten Verantwortlichkeiten haben. Deshalb sollten Sie keine zusätzlichen Aufgaben fügen dem View, ViewModeloder Modelwenn Sie nicht brauchen.

Unter keinen Umständen gehört die Erstellung des Fensters zum Model, da der Modelnicht einmal weiß, dass es so etwas wie eine GUI gibt.

Praktische Antwort

Hierbei handelt es sich um ein formularähnliches Tool mit einem Fenster und einer einzigen Schaltfläche "Senden" . Hier ist also ein schamloser Plug für eine verwandte Antwort von mir: Warum MVVM verwenden?

Um zusammenzufassen, was diese Antwort sagt: Halten Sie es einfach. Oh, und denken Sie an die oben genannte theoretische Antwort, um sie zu implementieren, sobald Ihr Fenster mit einer einzelnen Schaltfläche komplexer wird.

Peter
quelle