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 uniquement 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. En outre, comme View ne contient aucune logique, VM devrait d'abord vérifier si la création d'une nouvelle vue est nécessaire et, le cas échéant, renvoyer cette responsabilité à View, ce qui conduit à un ballonnement de code.
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.
Alors, est-il préférable de créer de nouvelles vues dans View ou ViewModel?
Réponses:
J'utilise l'injection de dépendances et une
IViewFactory
injection dans le modèle de vue pour respecter les deux contraintes.Un
ProductViewModel
(par exemple) appellethis.viewFactory.Show("Details", this)
à s'ouvrirProductDetailsView
avec lui-même commeProductViewModel
. Il pourrait également ouvrir une vue basée sur un autre modèle de vue avecthis.viewFactory.Show<ClientViewModel>()
.L'implémentation (il en existe plusieurs pour WinForms, simple Wpf Windows, un shell Wpf avec des tabulations, ...) est basée sur une
StructureMap
convention. Les vues désignent leur modèle de vue via uneIView<ProductViewModel>
interface.Ainsi, le modèle de vue ne connaît rien de la vue, sauf son rôle (vue par défaut, vue de détails, ...), et la vue ne contient aucun code pour créer une autre vue. En outre, les modèles de vue se trouvent dans un assemblage distinct qui ne fait référence à aucun assemblage Wpf.
la source
Réponse théorique
Si vous en avez un
ViewModel
, les actions qui ont des effets cosmétiques (par exemple, mettre en surbrillance un élément au survol de la souris) sont le travail duView
, tandis que les actions qui ont des effets "réels" (par exemple, l'apparition d'une nouvelle fenêtre) sont le travail duViewModel
.En tant que tel, la création d'une nouvelle fenêtre est un travail pour
ViewModel
. Cependant, ni la vue ni la personneViewModel
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 partage pas, il y a peu de valeur dans le débat un tel, parce que dans la pratique , il est pas la fin du monde si vous placez ce code dans leView
, et il est également pas beaucoup de travail pour le déplacer vers leViewModel
ultérieurement . 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. Voilà pourquoi vous ne pas ajouter des responsabilités supplémentaires à laView
,ViewModel
ouModel
si vous n'avez pas besoin.La création de la fenêtre n'appartient en aucun cas à la
Model
, car elleModel
n'est même pas consciente qu'il existe quelque chose comme une interface graphique.Réponse pratique
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.
la source