MVVM charger des données pendant ou après le ViewModel de la construction?
Ma question générique est que le titre, est-il préférable de charger des données au cours de ViewModel de la construction ou par la suite par quelques Chargé de la gestion des événements?
Je devine la réponse est après la construction en passant par quelques Chargé de la gestion des événements, mais je me demandais comment qui est le plus proprement coordonnée entre ViewModel et les Afficher?
Voici plus de détails sur ma situation et du problème particulier, je suis en train de résoudre:
Je suis en utilisant le framework MVVM Light ainsi que l'Unité de DI. J'ai quelques Vues imbriquées, chacune reliée à un correspondant ViewModel. Le Viewmodel sont liés à chaque Affichage de la racine de contrôle DataContext via le ViewModelLocator idée que Laurent Bugnion a mis en MVVM Light. Cela permet de trouver des ViewModels via une ressource statique et pour le contrôle de la durée de vie des ViewModels via une Injection de Dépendance cadre, dans ce cas l'Unité. Il permet aussi l'Expression Blend pour tout voir en ce qui concerne Viewmodel et comment les lier.
De toute façon, j'ai un parent qui a un ComboBox lié aux données à une ObservableCollection dans son ViewModel. La zone de liste déroulante du SelectedItem est aussi lié dans les deux sens) à une propriété du ViewModel. Lors de la sélection de la zone de liste déroulante des changements, c'est pour déclencher les mises à jour dans d'autres points de vue et des sous-vues. Actuellement, je suis à l'accomplissement de cette via le système de Messagerie qui se trouve dans MVVM Light. C'est tout fonctionne très bien et comme prévu lorsque vous choisissez les différents éléments dans la zone de liste déroulante.
Cependant, le ViewModel est d'obtenir ses données pendant le temps de construction par l'intermédiaire d'une série d'initialisation des appels de méthode. Cela semble être la seule à être un problème si je veux contrôler ce que l'initiale SelectedItem de la zone de liste déroulante est. En utilisant MVVM Light le système de messagerie d', j'ai actuellement mis en place où le setter de la ViewModel de la propriété SelectedItem est une radiodiffusion de la mise à jour et d'autres parties intéressées, Viewmodel enregistrer le message dans leurs constructeurs. Il semble que je suis en train d'essayer de régler le SelectedItem via le ViewModel au moment de la construction, qui n'a pas le droit de sous-Viewmodel être construit et s'inscrire encore.
Quelle serait la façon la plus propre de coordonner les données de charge et de réglage initial de SelectedItem dans le ViewModel? J'ai vraiment envie de coller avec de la en mettant que peu de choses dans la Vue de code-behind du raisonnable. Je pense que j'ai juste besoin d'un moyen pour le ViewModel de savoir quand des trucs a Chargé et qu'il peut alors continuer à charger les données et de finaliser la phase d'installation.
Merci d'avance pour vos réponses.
- Ne pouvez-vous pas d'avoir votre événement Chargé d'appeler une méthode sur le viewmodel?
- Oui, j'ai supposé que je pouvais. Je suis probablement plus de la pensée. Je suppose que mon hésitation est que j'ai été en mesure de lier le tout jusqu'à présent de façon déclarative dans le XAML. J'ai mis le DataContext et puis définissez les membres de toutes les liaisons dans un seul endroit. Est-il un moyen propre à cette fonction en XAML avec le contrôle du Chargé événement lié à un ViewModel méthode? Bien sûr, je ne pense pas que ce Dernier doit avoir de l'INTERFACE utilisateur spécifiques à la gestion des événements des paramètres de quoique ce soit.
Vous devez vous connecter pour publier un commentaire.
Pour les événements, vous devez utiliser le EventToCommand dans MVVM Light Toolkit. En utilisant cela, vous pouvez lier tout événement de tout élément de l'interface utilisateur relaycommand. Découvrez son article sur EventToCommand à
http://blog.galasoft.ch/archive/2009/11/05/mvvm-light-toolkit-v3-alpha-2-eventtocommand-behavior.aspx
Télécharger l'échantillon et ont un regard. Son grand. Vous n'aurez pas besoin de code-behind ensuite. En voici un exemple:
et le mode d'affichage peut être comme cette
si vous souhaitez la vue modèle, EventArgs, vous pouvez simplement définir PassEventArgsToCommand vrai:
et le modèle de vue sera comme
La solution suivante est similaire à celui déjà prévu et accepté, mais il n'utilise pas une commande dans le modèle de vue pour charger les données, mais un "mode normal".
Je pense que les commandes sont plus adaptés pour les actions de l'utilisateur (les commandes peuvent être disponibles et non disponibles au moment de l'exécution), c'est pourquoi une utilisation régulière d'un appel de méthode, mais aussi par la définition d'une interaction de déclenchement dans la vue.
Je suggère ceci:
Créer un modèle de vue de classe.
Instancier le modèle de vue de la classe dans le code xaml de la vue, par la création à l'intérieur de la
DataContext
propriété.De mettre en œuvre une méthode pour charger les données dans le modèle de vue, par exemple,
LoadData
.Configurer la vue, de sorte que cette méthode est appelée lors de l'affichage des charges.
Ceci est fait par une interaction de déclenchement de votre point de vue qui est liée à la méthode dans le modèle de vue (les références à "de Microsoft.De l'Expression.Les Interactions" et "le Système de.De Windows.L'interactivité" sont nécessaires):
Vue (xaml):
Ce qui fera appel à la
LoadData
méthode dans le ViewModel au moment de l'exécution lorsque la vue est chargé. C'est l'endroit où vous chargez vos données.Si la méthode dans le référentiel est une méthode asynchrone, vous pouvez faire la
LoadData
méthode async trop, mais ce n'est pas nécessaire dans chaque cas.Par la façon dont, en général, je voudrais ne pas charger les données dans le constructeur de la vue modèle.
Dans l'exemple ci-dessus l' (paramètre moins), le constructeur de la vue modèle est appelé lorsque le concepteur montre votre point de vue. Faire des choses complexes, ici, peut provoquer des erreurs dans le concepteur lors de l'affichage de votre point de vue (pour la même raison, je ne voudrais pas faire des choses complexes dans le point de vue du constructeur).
Dans certains scénarios de code dans la vue modèles de constructeurs peuvent même provoquer des problèmes lors de l'exécution, lorsque le point de vue des modèles de constructeurs s'exécute, définissez les propriétés de la vue du modèle, qui sont liés à des éléments dans la vue, tandis que la vue de l'objet n'est pas complètement terminé de créer.
Ok, alors. 🙂
Vous pouvez lier à une méthode dans le ViewModel par le biais d'un comportement.
Voici un lien qui va vous aider avec ça.
http://expressionblend.codeplex.com/
J'ai décidé d'avoir juste le code XAML de manière déclarative lié à un Chargé de gestionnaire d'événement dans la Vue de code-behind, qui à son tour vient d'appeler une méthode sur le ViewModel objet, à travers le point de Vue de l'élément racine UserControl DataContext.
C'était assez simple, direct, et propre solution. Je suppose que je m'attendais à un moyen de lier l'événement Chargé de la ViewModel objet de la même façon déclarative, vous pouvez avec ICommands dans le code XAML.
J'ai peut-être donné Klinger la réponse officielle de crédit, mais il a posté un commentaire à ma question, et pas une réponse. Donc, j'ai au moins fait une place sur son commentaire.
J'ai eu ce même problème en ce qui concerne les messages entre un parent de la fenêtre et une fenêtre enfant. Il suffit de changer l'ordre d'affichage des modèles sont créés dans votre ViewModelLocator classe. Assurez-vous que tous les modèles de vue qui dépend d'un message sont créés avant le modèle de vue qui envoie le message.
Par exemple, dans votre ViewModelLocator constructeur de la classe:
SimpleIoc.Default.Register<messageReceiverVm>(true);