Dans MVVM, ViewModel ou View devraient-ils être responsables de la création de nouvelles vues?

11

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?

Mac70
la source
1
Je ne comprends pas vraiment votre question. Que signifie «In View ou ViewModel»? Les ViewModels ne créent pas de vues, et les vues ne se créent certainement pas elles-mêmes.
Robert Harvey
1
Je veux dire laquelle de ces couches devrait être responsable de la création de nouvelles vues - le signal pour cela doit venir de quelque part lorsque l'action se produit. J'ai complètement exclu le modèle de cette question, car il ne devrait rien savoir du tout du frontend.
Mac70
Peut-être que je ne comprends pas votre question correctement, les deux ne devraient pas interférer avec votre point de vue. Si vous vouliez créer une nouvelle vue dans votre viewModel, y a-t-il une raison pour laquelle vous n'utilisez pas de cadres dans xaml pour modifier le contenu de la fenêtre avec une liaison à votre viewModel actuel?
Siobhan

Réponses:

8

J'utilise l'injection de dépendances et une IViewFactoryinjection dans le modèle de vue pour respecter les deux contraintes.

Un ProductViewModel(par exemple) appelle this.viewFactory.Show("Details", this)à s'ouvrir ProductDetailsViewavec 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 en existe plusieurs pour WinForms, simple Wpf Windows, un shell Wpf avec des tabulations, ...) est basée sur une StructureMapconvention. Les vues désignent leur modèle de vue via une 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 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.

Philippe
la source
7

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 du View, tandis que les actions qui ont des effets "réels" (par exemple, l'apparition 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 ViewModel. Cependant, ni la vue ni la personne ViewModelne 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 le View, et il est également pas beaucoup de travail pour le déplacer vers le ViewModelulté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 à la View, ViewModelou Modelsi vous n'avez pas besoin.

La création de la fenêtre n'appartient en aucun cas à la Model, car elle Modeln'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.

Peter
la source