如何在复合应用指南(PRISM)中获取复合子项中的激活事件

时间:2009-07-17 13:26:50

标签: silverlight silverlight-3.0

我正在使用CAG,而且我在使用TabControl区域时遇到了一些问题。我通过将视图(而不是PresentationModel)标记为IActiveAware来解决这个问题,我可以在激活/取消激活视图时获取事件。当复合很简单且TabItem是视图时,这很有效。

但是,在我的情况下,我在TabItem中有一个复合。它可以监听激活事件,但我想将这些事件传播给它的孩子,以便他们能够对它们做出反应。有没有办法做到这一点?我看了一下RegionContext,但它似乎不适用于我的情况(或者我做错了)。

可能是因为我错过了一些东西和一个附加的依赖或其他东西会解决我的问题吗?

3 个答案:

答案 0 :(得分:1)

我决定使用RegionContext在区域内传播IsActive状态。

将其设置为:

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

在我的标签视图(IActiveAware)上。然后在子视图中我可以听取更改:

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

剩下的问题是反过来会起作用。在选项卡视图上设置IsActive不会激活选项卡:( 我添加了自定义行为,现在它可以工作了。定制行为就像:

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上设置了:

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

希望解决别人的问题。或者也许有一种我更容易丢失的方式。

答案 1 :(得分:0)

你看过Prism EventAggregator吗?这可以实现为某种MessageBus或Mediator ...... 你可以Puplish活动,每个需要感兴趣的人都可以订阅它... 如果您查看棱镜样本,可以在文档中找到实现或其他内容...

答案 2 :(得分:0)

Prism EventAggregator(EA)对象允许您通过EA对象发布事件并订阅它们。这可以与单个发布者以及0,1或多个订阅者一起使用。当我需要在不捆绑在一起的应用程序的不同部分之间进行通信时,我通常使用EA。例如,Prism应用程序的shell中的菜单项可能需要调用另一个模块中的另一个视图。 EA允许您通过pub / sub执行此操作。但是,如果一个屏幕需要自己做一些事情,这个ifs通常更适合Command对象。