Dans mon application WPF, je souhaite créer une nouvelle vue. Où dois-je faire cela - dans ViewModel ou Model?
L'application est un outil de type formulaire (très simple pour l'instant) avec un seul bouton "envoyer". Dans le cas où l'une des cases à cocher est sélectionnée, une nouvelle fenêtre utilisant le même ViewModel devrait apparaître pour demander à l'utilisateur des détails supplémentaires. Aux fins de cette question, considérons simplement la nouvelle approche de la fenêtre sans considérer d'autres approches comme le panneau affiché/masqué.
Idéalement, dans View, il ne devrait pas y avoir de code. De plus, comme View ne contient aucune logique VM devrait initialement vérifier si la création d'une nouvelle vue est nécessaire, et - quand c'est le cas - renvoyer cette responsabilité à View, conduisant au code gonfler.
D'un autre côté, la création d'une nouvelle vue dans ViewModel viole le principe selon lequel ViewModel ne devrait rien savoir sur View.
Donc, est-il préférable de créer de nouvelles vues dans View ou ViewModel?
J'utilise l'injection de dépendances et un IViewFactory
injecté dans le modèle de vue pour respecter les deux contraintes.
Un ProductViewModel
(par exemple) appelle this.viewFactory.Show("Details", this)
pour ouvrir ProductDetailsView
avec lui-même comme ProductViewModel
. Il pourrait également ouvrir une vue basée sur un autre modèle de vue avec this.viewFactory.Show<ClientViewModel>()
.
L'implémentation (il y en a plusieurs pour WinForms, simple Wpf Windows, un Wpf Shell avec des onglets, ...) est basée sur une convention StructureMap
. Les vues désignent leur modèle de vue via un IView<ProductViewModel>
interface.
Ainsi, le modèle de vue ne connaît rien de la vue, sauf son rôle (vue par défaut, vue détaillée, ...), et la vue ne contient aucun code pour créer une autre vue. En outre, les modèles de vue se trouvent dans un assembly séparé qui ne fait référence à aucun assembly Wpf.
Si vous avez un ViewModel
, les actions qui ont des effets cosmétiques (par exemple, mettre un élément en surbrillance) sont le travail du View
, tandis que les actions qui ont des effets "réels" (par exemple, le lancement d'une nouvelle fenêtre ) sont le travail du ViewModel
.
En tant que tel, la création d'une nouvelle fenêtre est un travail pour le ViewModel
. Cependant, ni la vue ni le ViewModel
ne devraient savoir exactement comment créer une fenêtre, cela ne fait pas partie de leurs responsabilités et appartient à une classe différente.
Vous pourriez faire valoir que la création d'une nouvelle fenêtre est un travail pour le View
. Bien que je ne sois pas d'accord, un tel débat a peu de valeur, car dans la pratique, ce n'est pas la fin du monde si vous placez ce code dans le View
, et ce n'est pas beaucoup de travail pour le déplacer au ViewModel
à un stade ultérieur. La partie importante est que la logique de création d'une nouvelle fenêtre est contenue dans une classe indépendante, généralement une sorte de WindowFactory. Le point de MVVM, MVP, MVC, etc. est que vous avez des classes avec des responsabilités peu nombreuses et bien définies. C'est pourquoi vous n'ajoutez pas de responsabilités supplémentaires aux View
, ViewModel
ou Model
si vous n'en avez pas besoin.
En aucun cas, la création de la fenêtre n'appartient au Model
, car le Model
ne sait même pas qu'il existe quelque chose comme une interface graphique.
Il s'agit d'un "outil de type formulaire à une seule fenêtre avec un seul bouton" envoyer "" . Voici donc une fiche sans vergogne pour une réponse connexe: Pourquoi utiliser MVVM?
Pour résumer ce que dit cette réponse: Restez simple. Oh, et gardez à l'esprit la réponse théorique ci-dessus à mettre en œuvre une fois que votre fenêtre à bouton unique commencera à devenir plus complexe.