2012-11-28 1 views
2

I ont une coquille Caliburn.Micro (à savoir, une vue XAML vide pour contenir d'autres vues) rendue par un conducteur ViewModel. De là, j'ouvre un écran via:transition d'écran Caliburn.Micro par le conducteur

ActivateItem(...) 

Habituellement de la boîte de dialogue nouvellement affichée, l'utilisateur peut effectuer certaines opérations et cliquez sur les boutons (OK, Annuler, Construire ....) qui devrait chaque transition à un autre écran (dans le shell). Quels sont les bons moyens pour réaliser ce type d'action de dialogue/transitions d'écran de message?

  • simples .NET événements sont possibles - Ce ne serait pas une mauvaise idée?
  • CM IEventAggregator devrait également travailler en changeant la vue
  • Vérification de la coque du conducteur ViewModel résultat une fois qu'il a été fermé par TryClose() - Si possible, ne savent pas comment y parvenir dans CM.
  • Référence du shell Instance de conducteur à partir de cet écran (via IoC ou directement) - Cela semble un couplage fort.

Pourriez-vous s'il vous plaît aviser.

+0

trouvé un bon article qui décrit comment utiliser 'IEventAggregator': http://www.mindscapehq.com/blog/index.php/2012/02/01/caliburn -micro-part-4-the-event-aggregator/ – Wernight

Répondre

3

Mon approche préférée consiste à utiliser EventAggregator pour faciliter la messagerie entre les machines virtuelles. Cela fonctionne particulièrement bien lorsque vous avez plusieurs fenêtres qui écoutent un certain type d'événement (par exemple une interface de style Visual Studio avec plusieurs fenêtres d'outils qui peuvent afficher des propriétés contextuelles), mais cela semble un peu exagéré pour cette implémentation . Bien sûr, les avantages sont toujours un bon couplage entre les VM et un manque d'événements (ce qui est une bonne chose!)

Il semble que vous vouliez une boîte de dialogue modale pour faire apparaître et présenter une option, puis activer un autre écran une fois le premier est revenu.

Vous pouvez attacher un gestionnaire d'événement à l'événement Deactivated dans la machine virtuelle enfant qui se déclenche lorsqu'un élément est désactivé. Il passe également un booléen dans les arguments pour notifier si l'élément qui a été désactivé était fermé - vous pouvez vérifier cela et activer l'écran correspondant dans votre conducteur.

par exemple.

this.Deactivated += new EventHandler<DeactivationEventArgs>(WorkspaceViewModel_Deactivated); 

void WorkspaceViewModel_Deactivated(object sender, DeactivationEventArgs e) 
{ 
    if(e.WasClosed) // raise some event 
} 

Ensuite, passez un événement au conducteur, je ne serais pas vraiment le chemin de l'événement pour cela. L'alternative est de déclencher un message via l'agrégateur d'événements pour indiquer au conducteur qu'il doit ouvrir une fenêtre différente lorsque la machine virtuelle enfant se ferme.La même méthode peut être utilisé, mais il est découplé

this.Deactivated += new EventHandler<DeactivationEventArgs>(WorkspaceViewModel_Deactivated); 

void WorkspaceViewModel_Deactivated(object sender, DeactivationEventArgs e) 
{ 
    if(e.WasClosed) MainConductor.EventAggregator.Publish(new ActivateWindowMessage(typeof(SomeVM)); 
} 
+0

Vous avez raison sur mon objectif. Je vais essayer l'EventAggregator dans ma méthode "Ok" une fois que j'ai trouvé comment créer ce EventAggregator. Aussi, je trouve étrange que cette VM dépende du Shell/Main Conductor. Devrait être seulement l'inverse. – Wernight

+0

Il est, le vm devrait prendre soin de lui-même et le shell devrait prendre soin de montrer la vue appropriée, l'enfant vm devrait dicter ce que le vm parent devrait faire par messagerie, mais de manière indirecte afin de ne pas coupler les deux. J'aurais pu écrire un post déroutant! – Charleh

+0

Non non c'est bien, je cherchais plutôt à savoir lesquelles de mes solutions sont généralement mieux vues, pourquoi, et si possible comment les implémenter. J'ai utilisé la façon dont l'article a fait par l'injection du constructeur de l'IEvAgg afin qu'ils ne soient pas couplés étroitement. – Wernight

Questions connexes