【问题标题】:How to create a new view every time navigation occurs in PRISM?每次在 PRISM 中发生导航时如何创建新视图?
【发布时间】:2011-02-25 09:17:39
【问题描述】:

我正在为我的新项目使用 WPF4 和 PRISM4。

有一个包含多个视图的模块。 DI是统一完成的。当我第一次从 ViewA 导航到 ViewB 时,会创建 ViewB 并调用其构造函数。但是当我第二次、第三次尝试导航到 ViewB 时,没有创建 ViewB,而是重用了现有实例。

我使用 IRegionManager.RequestNavigate 进行导航。

我尝试将 TransientLifeTimeManager 传递给 RegisterType Unity 方法,但无济于事。

有没有办法配置 prism 和/或 unity 以在我每次导航到新视图时创建一个新视图?

谢谢。

【问题讨论】:

    标签: c# wpf prism-4


    【解决方案1】:

    执行此操作的正确方法是在您的 View 或 ViewModel 中实现 INavigationAware(Prism 将首先检查视图,如果未实现 INavigationAware,它还将检查 ViewModel)。

    您对 IsNavigationTarget 方法特别感兴趣,该方法告诉 Prism 是否应该重用当前的 View 实例,或者是否应该创建另一个实例来满足导航请求。因此,要始终创建一个新视图,您应该这样做:

    public class MyViewModel : INavigationAware {
        bool INavigationAware.IsNavigationTarget(NavigationContext navigationContext)
        {
            return false;
        }
    
        void INavigationAware.OnNavigatedFrom(NavigationContext navigationContext)
        {
        }
    
        void INavigationAware.OnNavigatedTo(NavigationContext navigationContext)
        {
        }
    }
    

    所有这些都在 Prism 4 文档的第 8 章中进行了更详细的解释;他们还有an illustration of how it works,这非常好,因为它还可以让您确切地知道可以在哪里以及如何连接。

    【讨论】:

    • 一个小附录,如果使用 MEF 进行依赖注入,您应该确保您的视图具有属性 [PartCreationPolicy(CreationPolicy.NonShared)。否则,ServiceLocator 将返回相同的实例,而不管IsNavigateTarget 逻辑如何。导航服务看到该区域已经包含该实例并激活它。困惑了很久。
    • 这实际上解决了我相反的问题。我的条件不正确,因此一直返回 false。
    【解决方案2】:

    方法是在您的视图或视图模型上实现 IRegionMemberLifetime,并在布尔属性 KeepAlive 中返回 false,如下所示:

    public class EmployeeDetailsViewModel : IRegionMemberLifetime
    {
        public bool KeepAlive
        {
            get { return false; }
        }
    }
    

    【讨论】:

    • 这不太正确,因为它的副作用是如果用户通过 UI 切换活动视图,那么您的 EmployeeDetailsView 将从该区域中删除,而不是简单地被停用。
    • 我确实假设他想在导航时删除视图,如果我弄错了,那么他会纠正我的。我们对他的要求的解释不同——我真的不明白为什么这会让你投票 -1,好像我的回答不正确一样。
    【解决方案3】:

    它在内部查找区域的ActiveViews 属性中的视图。如果其中不存在,它会创建一个新的并将其添加到 ActiveViews 以供将来使用。

    要完成您想做的事情,您需要在导航到任何视图之前删除或清除 ActiveView 集合。

    示例:

    public static class RegionManagerExtensions
    {
        public static void RequestNavigateEx(this IRegionManager regionManager, String regionName, Uri source)
        {
            if (regionManager != null)
            {
                IRegion region = regionManager.Regions[regionName];
    
                if (region != null)
                {
                    foreach (Object view in region.ActiveViews)
                    {
                        region.Remove(view);
                    }
    
                    regionManager.RequestNavigate(regionName, source);
                }
            }
        }
    }
    

    【讨论】:

    • 嘿,我尝试这样做并最终得到一个空白视图。有什么我想念的吗?
    • 视图不必存在于 Active View 属性中;如果视图存在于 Views 属性中,也不会重新创建视图。
    猜你喜欢
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 2012-03-08
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 2022-12-13
    相关资源
    最近更新 更多