Как получить события активации у составных детей в Руководстве по составному приложению (PRISM) - PullRequest
0 голосов
/ 17 июля 2009

Я использую CAG, и у меня есть некоторые проблемы с использованием области TabControl. Я понял, что, пометив представление (а не PresentationModel) как IActiveAware, я могу получить событие, когда представление активируется / деактивируется. Это хорошо работает, когда композит прост, а TabItem является представлением.

Однако в моем случае у меня есть составная часть внутри TabItem. Он может прослушивать события активации, но я хотел бы передать эти события своим дочерним элементам, чтобы они могли реагировать на них. Есть ли способ сделать это? Я взглянул на RegionContext, но в моем случае он не работает (или, возможно, я делаю это неправильно).

Может ли быть, что я что-то упустил, и пристрастная зависимость или что-то еще решит мою проблему?

Ответы [ 3 ]

1 голос
/ 20 июля 2009

Я решил использовать 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());
                    }
                };

Надеюсь, что это решит чужую проблему. Или, может быть, я упускаю более простой способ.

0 голосов
/ 18 июля 2009

Объект Prism EventAggregator (EA) позволяет публиковать события и подписываться на них через объект EA. Это может использоваться с одним издателем и 0, 1 или многими подписчиками. Обычно я использую советник, когда мне нужно общаться между различными частями приложения, которые не связаны между собой. Например, пункту меню в оболочке приложения Prism может потребоваться вызвать другое представление в другом модуле. Советник позволяет вам делать это через pub / sub. Однако если экран должен заставить что-то происходить сам по себе, это часто лучше подходит для объекта Command.

0 голосов
/ 17 июля 2009

Вы смотрели на Prism EventAggregator? Это может быть реализовано как своего рода MessageBus или Mediator ... Вы можете публиковать события, и каждый, кто должен быть заинтересован, может подписаться на него ... Если вы посмотрите на образцы призмы, вы найдете реализацию или что-то в документации ...

...