2009-07-17 7 views
0

J'utilise le CAG et j'ai des problèmes avec la région TabControl. J'ai calculé qu'en marquant la vue (et non le PresentationModel) comme IActiveAware je peux obtenir un événement quand la vue est activée/désactivée. Cela fonctionne bien lorsque le composite est simple et que TabItem est la vue.Comment obtenir des événements d'activation dans les enfants composites dans PRISM (Composite Application Guidance)

Cependant, dans mon cas, j'ai un composite dans le TabItem. Il peut écouter les événements d'activation mais j'aimerais propager ces événements à ses enfants afin qu'ils puissent y réagir. Y a-t-il un moyen de le faire? J'ai regardé le RegionContext mais cela ne semble pas fonctionner dans mon cas (ou peut-être que je le fais mal).

Se pourrait-il que je manque quelque chose et qu'une dépendance attachée ou quelque chose d'autre résoudrait mon problème?

Répondre

1

J'ai décidé d'utiliser RegionContext pour propager l'état IsActive dans la région.

le configurer comme:

Regions:RegionManager.RegionContext="{Binding Path=IsActive, Mode=TwoWay}" 

sur mon point de vue de l'onglet (qui est IActiveAware). Ensuite, dans la vue enfant, je peux écouter les changements:

RegionContext.GetObservableContext((DependencyObject)View).PropertyChanged += new PropertyChangedEventHandler(VehiclesPresentationModel_PropertyChanged); 


private void VehiclesPresentationModel_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    if (e.PropertyName == "Value") 
    { 
     IsActive = (bool)RegionContext.GetObservableContext((DependencyObject)View).Value; 
    } 
} 

Le problème restant était que l'inverse fonctionnerait. . Réglage IsActive sur la vue de l'onglet ne pas actif l'onglet :( j'ai ajouté un comportement personnalisé et maintenant il fonctionne Le bahavior personnalisé est comme:

public class RegionReverseActiveAwareBehavior : RegionBehavior 
{ 
    public const string BehaviorKey = "RegionReverseActiveAwareBehavior"; 


    protected override void OnAttach() 
    { 
     Region.Views.CollectionChanged += new NotifyCollectionChangedEventHandler(Views_CollectionChanged); 
    } 


    private void Views_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      foreach (var item in e.NewItems) 
      { 
       IActiveAware activeAwareItem = item as IActiveAware; 
       if (activeAwareItem != null) 
       { 
        activeAwareItem.IsActiveChanged += new EventHandler(activeAwareItem_IsActiveChanged); 
       } 
      } 
     } 
     if (e.Action == NotifyCollectionChangedAction.Remove) 
     { 
      foreach (var item in e.OldItems) 
      { 
       IActiveAware activeAwareItem = item as IActiveAware; 
       if (activeAwareItem != null) 
       { 
        activeAwareItem.IsActiveChanged -= new EventHandler(activeAwareItem_IsActiveChanged); 
       } 
      } 
     } 
    } 

    private void activeAwareItem_IsActiveChanged(object sender, EventArgs e) 
    { 
     IActiveAware activeAware = sender as IActiveAware; 
     if (activeAware != null && 
      activeAware.IsActive) 
     { 
      Region.Activate(activeAware); 
     } 
    } 
} 

Et puis je l'ai mis sur le TabControl avec:

 RegionManager.GetObservableRegion(tabRegion).PropertyChanged += 
      (sender, args) => 
       { 
        if (args.PropertyName == "Value") 
        { 
         IRegion region = RegionManager.GetObservableRegion(tabRegion).Value; 
         region.Behaviors.Add(RegionReverseActiveAwareBehavior.BehaviorKey, new RegionReverseActiveAwareBehavior()); 
        } 
       }; 

espoir qui résout quelqu'un le numéro d'un autre. Ou peut-être il y a un moyen plus facile que je me manque.

0

Avez-vous regardé Prism EventAggregator? Cela peut être implémenté comme une sorte de MessageBus ou Mediator ... Vous pouvez personnaliser les événements et tous ceux qui ont besoin d'être intéressés peuvent s'y abonner ... Si vous regardez dans les exemples de prisme, vous trouverez une implémentation ou quelque chose dans les docs.

+0

je pouvais mais je devrais passer beaucoup d'informations aux vues de l'enfant de travailler si ou pas son parent qui a été activé :( – R4cOON

0

L'objet Prism EventAggregator (EA) vous permet de publier des événements et de s'y abonner via l'objet EA. Cela peut être utilisé avec un seul éditeur et 0, 1 ou plusieurs abonnés. J'utilise généralement l'EA lorsque j'ai besoin de communiquer entre différentes parties d'une application qui ne sont pas liées ensemble. Par exemple, un élément de menu dans le shell d'une application Prism peut avoir besoin d'invoquer une autre vue dans un module différent. L'EA vous permet de le faire via pub/sub. Cependant, si un écran a besoin de faire quelque chose par lui-même, ceci est souvent mieux adapté à l'objet Command.

Questions connexes