Wpf 视图导航棱镜

Wpf 视图导航棱镜,wpf,view,navigation,prism,Wpf,View,Navigation,Prism,嘿,伙计们, 我正在使用prism 4来实现我的演示, 问题是,我正在使用包含区域的视图,现在我想导航到同一范围下视图的其他实例,因此我将视图的KeepAlive属性设置为false,以便在导航中,视图将从区域中删除,新视图将出现,但我一直获得区域名称已存在异常。 如何在同一视图的几个实例之间导航,这些实例同时只包含一个应该在内存中的区域 谢谢 Eran听起来您想使用一个具有导航功能的作用域管理器。您看到区域名称已存在异常的原因是,在同一RegionManager中有多个具有相同名称的区域 默认

嘿,伙计们, 我正在使用prism 4来实现我的演示, 问题是,我正在使用包含区域的视图,现在我想导航到同一范围下视图的其他实例,因此我将视图的KeepAlive属性设置为false,以便在导航中,视图将从区域中删除,新视图将出现,但我一直获得区域名称已存在异常。 如何在同一视图的几个实例之间导航,这些实例同时只包含一个应该在内存中的区域 谢谢
Eran

听起来您想使用一个具有导航功能的作用域管理器。您看到区域名称已存在异常的原因是,在同一RegionManager中有多个具有相同名称的区域

默认情况下,PRISM不支持带有导航的作用域RegionManager,但如果您使用自定义RegionBehaviors,则很容易将其添加到中。基本上,您需要做的是创建一个接口,然后在视图或视图模型上实现该接口。然后,创建一个RegionBehavior来查找该接口,如果它满足要求,则为该视图创建一个新的RegionManager实例

以下是界面的外观:

public interface IRegionScopeAware
{
    bool IsRegionManagerScoped { get; }
}
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());
    }
}
下面是区域行为可能的样子:

public interface IRegionScopeAware
{
    bool IsRegionManagerScoped { get; }
}
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());
    }
}

这里也有同样的问题。导航示例似乎没有看到这一点。