W mojej aplikacji WPF chcę utworzyć nowy widok. Gdzie mam to zrobić - w ViewModel lub Model ?
Aplikacja jest (jak na razie bardzo prostym) narzędziem podobnym do jednego okna z pojedynczym przyciskiem „wyślij”. W przypadku zaznaczenia jednego z pól wyboru powinno pojawić się nowe okno z tym samym ViewModel, aby poprosić użytkownika o dodatkowe szczegóły. Na potrzeby tego pytania rozważmy tylko nowe podejście do okna bez rozważania innych podejść, takich jak pokazany / ukryty panel.
Idealnie byłoby, gdyby w widoku nie było żadnego kodu. Ponadto, ponieważ View nie ma w sobie żadnej logiki, VM musiałoby początkowo sprawdzić, czy konieczne jest utworzenie nowego widoku, i - gdy jest - odesłać tę odpowiedzialność z powrotem do View, co prowadzi do rozdęcia kodu.
Z drugiej strony, tworzenie nowego widoku w ViewModel narusza zasadę, że ViewModel nie powinien wiedzieć o View.
Czy lepiej tworzyć nowe widoki w View lub ViewModel?
Odpowiedzi:
Używam wstrzykiwania zależności i
IViewFactory
wstrzykiwanego do modelu widoku, aby przestrzegać obu ograniczeń.A
ProductViewModel
(na przykład) wzywathis.viewFactory.Show("Details", this)
do otwarcia sięProductDetailsView
ze sobą jakoProductViewModel
. Może również otworzyć widok oparty na innym modelu widoku za pomocąthis.viewFactory.Show<ClientViewModel>()
.Implementacja (w rzeczywistości jest ich kilka dla WinForm, proste Wpf Windows, powłoka Wpf z kartami, ...) oparta jest na
StructureMap
konwencji. Widoki oznaczają ich model widoku za pośrednictwemIView<ProductViewModel>
interfejsu.Zatem model widoku nie wie nic o widoku oprócz jego roli (widok domyślny, widok szczegółów, ...), a widok nie zawiera kodu do utworzenia innego widoku. Ponadto modele widoków znajdują się w osobnym zestawie, który nie odwołuje się do żadnego zestawu Wpf.
źródło
Teoretyczna odpowiedź
Jeśli masz
ViewModel
, akcje, które mają efekty kosmetyczne (np. Podświetlenie elementu po najechaniu myszką) są zadaniemView
, podczas gdy akcje, które mają „rzeczywiste” efekty (np. Odrodzenie nowego okna), są zadaniemViewModel
.W związku z tym utworzenie nowego okna jest zadaniem dla
ViewModel
. Jednak ani widok, ani nieViewModel
powinni wiedzieć, jak dokładnie utworzyć okno, co nie należy do ich obowiązków i należy do innej klasy.Można argumentować, że utworzenie nowego okna jest zadaniem
View
. Chociaż nie zgadzam się, taka debata ma niewielką wartość, ponieważ w praktyce umieszczenie tego kodu w kodzie nie jest końcem świataView
, a przeniesienie goViewModel
na później nie jest zbyt trudne . Ważną częścią jest to, że logika tworzenia nowego okna jest zawarta w niezależnej klasie, zwykle pewnego rodzaju WindowFactory. Istotą MVVM, MVP, MVC itp. Jest to, że masz zajęcia z niewielką liczbą dobrze określonych obowiązków. Dlatego nie należy dodawać dodatkowe obowiązki doView
,ViewModel
lubModel
jeśli nie trzeba.W żadnym wypadku tworzenie okna nie należy do
Model
, ponieważModel
nawet nie zdaje sobie sprawy, że istnieje coś takiego jak GUI.Praktyczna odpowiedź
Chodzi o „narzędzie podobne do formularza w jednym oknie z pojedynczym przyciskiem„ wyślij ” . Oto więc bezwstydna wtyczka do mojej podobnej odpowiedzi: Dlaczego warto korzystać z MVVM?
Podsumowując, co mówi ta odpowiedź: Uprość to. Aha, i pamiętaj o teoretycznej odpowiedzi powyżej, aby wdrożyć, gdy okno jednego przycisku zacznie się bardziej skomplikować.
źródło