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?
Antworten:
Ich verwende die Abhängigkeitsinjektion und eine
IViewFactory
in das Ansichtsmodell injizierte, um beide Einschränkungen zu berücksichtigen.Ein
ProductViewModel
(zum Beispiel) Aufrufthis.viewFactory.Show("Details", this)
,ProductDetailsView
mit sich selbst als zu öffnenProductViewModel
. Es könnte auch eine Ansicht basierend auf einem anderen Ansichtsmodell mit öffnenthis.viewFactory.Show<ClientViewModel>()
.Die Implementierung (es gibt tatsächlich mehrere für WinForms, einfaches Wpf-Windows, eine Wpf-Shell mit Registerkarten, ...) basiert auf einer
StructureMap
Konvention. Die Ansichten bestimmen ihr Ansichtsmodell über eineIView<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.
quelle
Theoretische Antwort
Wenn Sie eine haben
ViewModel
, sind Aktionen mit kosmetischen Effekten (z. B. Hervorheben eines Elements beim Mouseover) die Aufgabe vonView
, während Aktionen mit "echten" Effekten (z. B. das Laichen eines neuen Fensters) die Aufgabe von sindViewModel
.Das Erstellen eines neuen Fensters ist daher eine Aufgabe für die
ViewModel
. Weder die Ansicht noch dieViewModel
sollten 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ügenView
, und es auch nicht viel Arbeit ist, ihn zuViewModel
einem 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 demView
,ViewModel
oderModel
wenn Sie nicht brauchen.Unter keinen Umständen gehört die Erstellung des Fensters zum
Model
, da derModel
nicht 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.
quelle