2010-03-28 3 views
1

J'utilise le framework MVVM Light ainsi que Unity for DI. J'ai des Vues imbriquées, liées chacune à un ViewModel correspondant. Les ViewModels sont liés au contrôle racine de chaque vue DataContext via l'idée ViewModelLocator que Laurent Bugnion a placée dans MVVM Light. Cela permet de trouver ViewModels via une ressource statique et de contrôler la durée de vie de ViewModels via une infrastructure d'injection de dépendances, en l'occurrence Unity. Il permet également à Expression Blend de voir tout ce qui concerne ViewModels et comment les lier. Comme je l'ai dit, les vues ont une bonne dose d'imbrication, mais les ViewModels ne savent rien vraiment l'un de l'autre. Une vue parent se lie à son ViewModel correspondant via la ressource statique ViewModelLocator (qui utilise Unity pour contrôler la construction et la durée de vie de l'objet ViewModel). Cette vue parent contient un contrôle utilisateur qui est une autre sous-vue, qui va ensuite et obtient son ViewModel correspondant via le ViewModelLocator ainsi. Les ViewModels n'ont pas de références les uns aux autres ou ne connaissent aucune hiérarchie les uns par rapport aux autres. Voici un exemple de la façon dont ViewModels interagissent via la messagerie. J'ai une vue parent qui a une base de données ComboBox à une ObservableCollection dans son ViewModel. Le SelectedItem de ComboBox est également lié (bidirectionnel) à une propriété sur le ViewModel. Lorsque la sélection de la zone de liste modifiable change, cela déclenche des mises à jour dans d'autres vues et sous-vues. Actuellement, j'accomplis cela via le système de messagerie que l'on trouve dans MVVM Light. Donc, je me demande quelle serait la meilleure pratique pour obtenir des informations d'un ViewModel à l'autre? Dans ce cas, ce que je dois transmettre à sous-ViewModels est fondamentalement un utilisateur Guid représentant l'utilisateur actuellement connecté. Le View parent le plus haut (bien, ViewModel) connaîtra cette information, mais je ne suis pas sûr de savoir comment l'obtenir dans les sous-ViewModels.Passer ou Obtenir une valeur de Parent ViewModel vers Sub-ViewModel?

Certaines approches possibles que je peux penser:

  • Si le sous-ViewModel demander à la ressource statique ViewModelLocator pour une référence au même objet de la vue parent utilise et accéder à la propriété que façon? Il semble que ViewModels traversant les propriétés de l'autre n'est pas très propre et les couple ensemble inutilement.

  • J'utilise déjà la messagerie pour notifier les sous-vues que l'utilisateur a sélectionné un nouvel élément dans la zone de liste déroulante et mise à jour en conséquence. Mais le type d'objet qui est sélectionné dans le ComboBox n'est pas vraiment directement lié à cette valeur de données que les sous-vues ont besoin.

+0

En fait, un identifiant d'utilisateur authentifié n'est pas la seule valeur que je dois obtenir du ViewModel le plus haut; Il existe également une valeur de date de début et de fin dans les contrôles DatePicker qui doivent transmettre les sous-ViewModels pour filtrer certaines données. – mkmurray

Répondre

0

j'ai décidé de sous-ViewModels publier un message demandant les informations nécessaires et ensuite la machine virtuelle parente abonner à ce type de message et jeton de clé. Je ne veux pas abuser de ce moyen de communication, mais je pense qu'il sera efficace pour quelques morceaux de données que j'ai du mal à trouver des moyens de faire défiler la hiérarchie de View. Jusqu'à présent, la plupart des données transmises étaient en réponse à des événements, mais toutes les données ne peuvent pas être transmises de cette manière, en particulier si les données sont acquises ou si l'événement se produit sur un écran différent avant la nouvelle vue. est même construit et lu pour recevoir les données.

J'ai eu une conversation sur Twitter avec des noms bien connus dans cet espace (Glenn Block, John Papa et Rob Eisenberg). Ils ont suggéré un certain nombre de choses comme un modèle de visiteur, mais je n'étais pas sûr que cela fonctionnerait si bien sans une hiérarchie de machines virtuelles. Cela peut être dû au fait que mon design a été plutôt View-first, par opposition à une approche ViewModel-first. Une autre suggestion qui aurait pu être réalisable serait de modifier mon utilisation de ViewModelLocator et de Injection de dépendances pour inclure la possibilité de transmettre les valeurs de données aux sous-machines virtuelles au moment de la création. J'ai eu un peu de mal à l'imaginer à cause de la nature statique du VML, et j'ai décidé que la solution de demande de message que je me proposais serait plus simple et plus simple pour l'instant. Je vais probablement devoir repenser la solution s'il finit par y avoir trop de morceaux de données tombant dans cette situation.

3

J'ai vu essentiellement deux approches à cela. Pour la communication inter-VM générale, le modèle d'agrégateur d'événements fonctionne très bien.

Pour les hiérarchies de machines virtuelles, l'utilisation d'un modèle de visiteur peut toutefois être meilleure. Avec un visiteur, vous pouvez avoir des informations qui circulent dans la hiérarchie, par exemple en donnant automatiquement à chaque enfant une référence à la machine virtuelle parente.

Vous pouvez également le faire avec EA, mais le défi consiste à transmettre suffisamment d'informations dans la charge utile du message pour que les enfants sachent que c'est quelque chose dont ils devraient se soucier.

En ce qui concerne VM locator, absolument pas! Le truc de localisateur de VM est strictement pour la liaison dans l'interface utilisateur il ne devrait pas se surface en dehors de ce contexte (de manière optimale).

Mon .02 $ Glenn

+0

Grande réponse en général et une partie de celui-ci est proche de la solution choisie. Cependant, je n'ai pas de hiérarchie de machines virtuelles, seules les vues sont imbriquées et les machines virtuelles complémentaires sont des données liées à chaque vue. Je suppose que je me suis retrouvé avec quelque chose comme EA; Je posterai une réponse expliquant ce que j'ai fait. – mkmurray

Questions connexes