просматривает навигационную призму

#wpf #view #navigation #prism

#wpf #Вид #навигация #призма

Вопрос:

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

Комментарии:

1. Здесь та же проблема. Похоже, что пример навигации этого не предвидел.

Ответ №1:

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

По умолчанию PRISM не поддерживает RegionManagers с навигацией, но это довольно легко добавить, если вы используете пользовательские 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 amp;amp; 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;
        }