2009-07-17 8 views
0

私はCAGを使用していますが、TabControl領域を使用していくつかの問題があります。私はビューをアクティブ化/非アクティブ化したときにイベントを取得できるIActiveAwareとしてビュー(PresentationModelではない)をマーキングすることでそれを解決しました。コンポジットがシンプルで、TabItemがビューである場合はうまく動作します。コンポジットアプリケーションガイダンス(PRISM)でコンポジット子どものアクティベーションイベントを取得する方法

しかし私の場合は、TabItemの中にコンポジットがあります。それはアクティベーションイベントを聞くことができますが、私はこれらのイベントを子どもたちに伝えて、彼らがそれに反応できるようにしたいと思います。それをする方法はありますか?私はRegionContextを見ましたが、私の場合は動作していないようです(あるいは多分私が間違っている)。

私は何かを見逃している可能性がありますか、それに付随する依存関係か何かが私の問題を解決するでしょうか?

答えて

1

リージョン内でIsActive状態を伝播するためにRegionContextを使用することに決めました。 (IActiveAwareである)私のタブ表示に

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

は、としてそれを設定します。子どもの視点で私は変更を聞くことができます:

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; 
    } 
} 

残りの問題は、その逆が働くことでした。

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); 
     } 
    } 
} 

そして私がTabControlにそれを設定:

。タブビューでのisActiveを設定すると、カスタムbahaviorが似ているアクティブでないタブ:( 私はカスタム動作を追加して、今それが動作し誰か他の人の問題を解決し
 RegionManager.GetObservableRegion(tabRegion).PropertyChanged += 
      (sender, args) => 
       { 
        if (args.PropertyName == "Value") 
        { 
         IRegion region = RegionManager.GetObservableRegion(tabRegion).Value; 
         region.Behaviors.Add(RegionReverseActiveAwareBehavior.BehaviorKey, new RegionReverseActiveAwareBehavior()); 
        } 
       }; 

希望は。それとも私ができる

0

あなたはPrism EventAggregatorを見ましたか?これはMessageBusやMediatorのようなものとして実装することができます... イベントをプッシュしたり、興味を持っている必要がある人は誰でも参加できます。 プリズムのサンプルを見ると、ドキュメント内に実装などが見つかります。 ..

+0

。私が欠けている簡単な方法がありますが、その後、私はどうか動作するように子ビューに多くの情報を伝えなければならないでしょうまたは活性化されたその親ではない:( – R4cOON

0

Prism EventAggregator(EA)オブジェクトを使用すると、イベントをパブリッシュし、EAオブジェクトを通じてイベントを購読することができます。これは、1つのパブリッシャと0,1、または多数のユーザで使用できます。私は、アプリケーションの異なる部分の間で通信する必要があるときに、一般にEAを使用します。たとえば、Prismアプリケーションのシェルのメニュー項目は、別のモジュールの別のビューを呼び出す必要があります。 EAではpub/subを使ってこれを行うことができます。しかし、画面が何かを自分自身で行う必要がある場合、このifはCommandオブジェクトに適しています。

関連する問題