2017-04-23 1 views
0

J'ai rencontré le problème où un message se déclenchera plusieurs fois, car un message est enregistré plusieurs fois lorsqu'il est enregistré dans le constructeur d'une vue. Une grande majorité des S.O. messages, sites, blogs montrent un exemple comme celui-ci:MvvmLight Messaging - Quelle est la manière correcte d'enregistrer et de désinscrire un message?

public ConstructorOfView() { 
    DataContext = viewModelObject; 
    Messenger.Default.Register<SomeClass>(recipient, token, method); 
} 

public someUnloadOrNavigateFromMethod() { 
    Messenger.Default.Unregister<SomeClass>(parameters and more); 
} 

désenregistrement semble avoir aucun effet pour moi. Certains exemples disent d'enregistrer des messages dans le ViewModel. Cela n'a pas de sens pour moi pour deux raisons: 1) Si vous définissez le DataContext d'une page à un ViewModel, le constructeur ViewModel est appelé deux fois de nouveau tout comme le constructeur de vue. 2) Si vous enregistrez un message à l'intérieur du ViewModel, comment dites-vous exactement à la vue de déclencher une méthode, autre que la rendre publique statique, qui affiche une boîte de dialogue de message? La troisième option consistant simplement à appeler un élément lié à l'interface utilisateur comme une boîte de dialogue à l'intérieur du viewmodel semble violer le concept de MvvM.

Quelle est la bonne façon d'enregistrer et de désinscrire des messages? Certains messages ont recommandé d'avoir l'appel de viewmodel Cleanup(), mais d'une manière ou d'une autre, vous devez enregistrer des messages dans viewmodel, mais je ne vois pas comment, si vous définissez le destinataire du message comme viewmodel, comment le viewmodel appeler une méthode non-public-statique dans la vue pour modifier/afficher l'interface utilisateur?

Répondre

0

J'utilise normalement un modèle où mes modèles de vue sont enregistrés dans un conteneur IOC (jetez un oeil à la classe VireModelLocator dans l'application de démarrage MVVMLight) et enregistrez les messages dans le constructeur ViewModel. De cette façon, puisque la création ViewModel est gérée par IOC, vous n'aurez aucun problème avec plusieurs créations de la vue concernée, l'enregistrement du message ne se produira qu'une seule fois. Gardez également à l'esprit que l'enregistrement et le désenregistrement des messages vous mèneront facilement à un monde de bogues très difficiles à trouver où vous envoyez un message, mais pour une raison quelconque, il n'y a pas de jet enregistré par handler.

Je voudrais également ajouter que 99% de l'interaction vue/viewmodel devrait se produire throgh liaison.

Je suggère fortement de revoir le modèle d'application WPF fourni par MvvmLight afin d'identifier et de comprendre les modèles de programmation.

+0

Merci pour la réponse. Une chose que je suis confus. Si vous enregistrez des messages dans le viewmodel, comment changez-vous ou affichez-vous un UI comme une boîte de dialogue, quand la boîte de dialogue doit être manipulée dans la vue et non dans le viewmodel? C'est ce qui n'a aucun sens pour l'enregistrement des messages dans un viewmodel. – ShrimpCrackers

+0

Je comprends votre doute, et en quelque sorte d'accord avec elle. Le fait est qu'il y a beaucoup de solutions à cela, également basées sur la plate-forme pour laquelle vous écrivez votre code. Supposant que vous écrivez une application wpf pour Windows, le premier pourrait être: ne pas être un extrémiste mvvm et appeler directement MessageBox.Show dans votre gestionnaire de messages. Je le fais parfois, cela fonctionne et cela viole certains principes du MVVM mais peut vous faire économiser des centaines de lignes de code. Deuxièmement: repensez comment vous voulez montrer des messages à vos utilisateurs et utilisez la liaison à certains contrôles de l'interface utilisateur pour afficher votre message. Troisièmement: au lieu d'une boîte de dialogue, affichez une nouvelle vue popup. –