просмотр навигационной призмы - PullRequest
1 голос
/ 08 мая 2011

Привет, ребята,
Я использую призму 4 для реализации своей презентации, дело в том, что я использую представление, содержащее регион, теперь я хочу перейти к другому экземпляру представления в той же области, поэтомуустановите для свойства KeepAlive представления значение false, чтобы при навигации представление было удалено из региона и появилось новое представление, но я продолжаю получать имя региона, уже существует исключение.
как я могу перемещаться между несколькими экземплярамитого же представления, которые содержат регион (только один должен быть в памяти в то время)
Спасибо
Eran

1 Ответ

0 голосов
/ 29 июня 2012

Похоже, вы хотите использовать RegionManager с навигацией.Причина, по которой вы видите, что имя региона уже существует, заключается в том, что у вас есть несколько регионов с одинаковым именем в одном и том же RegionManager.

По умолчанию PRISM не поддерживает RegionManager с областью действия с навигацией, но этодовольно легко добавить это, если вы используете пользовательские RegionBehaviors.По сути, вам нужно создать интерфейс, а затем реализовать этот интерфейс в своем представлении или модели представления.Затем создайте RegionBehavior, который ищет этот интерфейс, и, если он отвечает требованиям, создайте новый экземпляр RegionManager для этого представления.

Вот как может выглядеть интерфейс:

public interface IRegionScopeAware
{
    bool IsRegionManagerScoped { get; }
}

А вот как может выглядеть поведение RegionBehavior:

public class RegionScopeAwareBehavior : RegionBehavior
{
    #region Overrides of RegionBehavior

    protected override void OnAttach()
    {
        Region.Views.CollectionChanged += ViewsOnCollectionChanged;
        ApplyScopedRegionManager(Region.Views.OfType<FrameworkElement>());
    }

    #endregion

    private static void ViewsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems == null || e.Action != NotifyCollectionChangedAction.Add) return;
        ApplyScopedRegionManager(e.NewItems.OfType<DependencyObject>());
    }

    private static void ApplyScopedRegionManager(IEnumerable<DependencyObject> views)
    {
        if (views == null) return;
        foreach (var view in views)
        {
            ApplyScopedRegionManager(view);
        }
    }

    private static void ApplyScopedRegionManager(DependencyObject view)
    {
        if (view == null) return;
        IRegionScopeAware scopeAware = view as IRegionScopeAware;
        if (scopeAware == null && view is FrameworkElement)
            scopeAware = ((FrameworkElement) view).DataContext as IRegionScopeAware;
        if (scopeAware != null)
            ApplyScopedRegionManager(scopeAware, view);
    }

    private static void ApplyScopedRegionManager(IRegionScopeAware scopeAware, DependencyObject view)
    {
        if (view == null) return;
        if (scopeAware == null) return;
        if (scopeAware.IsRegionManagerScoped)
            RegionManager.SetRegionManager(view, new RegionManager());
    }
}

И не забывайте, что вам нужно зарегистрировать свое поведение RegionBehavior.Я предлагаю зарегистрировать его как RegionBehavior по умолчанию в загрузчике следующим образом:

        protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
        {
            IRegionBehaviorFactory factory = base.ConfigureDefaultRegionBehaviors();
            factory.AddIfMissing(typeof(RegionScopeAwareBehavior).Name, typeof(RegionScopeAwareBehavior));
            return factory;
        }
...