2016-08-19 70 views
0

我在棱镜只有2天知道,所以不要判断我的任何错误的假设,当试图解释以下navigaton问题。棱镜请求导航的行为

假设我们只有1个区域和2个不同的视图。视图A从自定义RegionBehavior启动时加载到该区域。我使用的是在该行为中的RegionManager上的RequestNavigate。我没有找到任何更好的解决方案来设置初始视图,但这不是这里的主要观点。

现在我们在每个视图上都有一个按钮来导航到另一个视图。这些命令在每个ViewModel上执行并再次调用RequestNavigate。 我使用常量来注册容器(Autofac)的导航视图,我使用相同的常量来调用RequestNavigate。 一切正常,一见钟情。但后来我意识到每次切换视图时,都会创建一个新的视图和视图模型。更糟糕的是,RegionManager仍然保存着所有先前的引用,这似乎是内存泄漏。我可以切换到现在将我的视图注册为单例,但我仍然不明白为什么RegionManager会以这种方式工作。为什么他不知道他已经知道一个观点,我请求导航并激活该观点而不是创建新观点?我还有什么使用常量作为名称呢?

然后我发现这个帖子PRISM WPF - Navigation creates new view every time,事实上这解决了这个问题。只要我使用该类型的名称来注册视图,一切都按预期工作。视图模型和视图模型是在第一次使用时创建的,然后在再次请求导航时重复使用。

我仍然可以实现IRegionMemberLifetime并在KeepAlive上返回false,如果这不是我想要的行为,并且我更喜欢每次都创建新的views/viewmodels。然后至少前者从RegionManager中删除。 如果我不想擦除它们并仍然希望这种旧的内存消耗行为,我仍然可以实现INavigationAware并在IsNavigationTarget中返回false。通过这种方式,RegionManager每次都会创建新的实例,并且仍然保留对旧实例的引用。 另一种方式我不能阻止他创建新的实例注册名称不等于类型名称。在这种情况下甚至没有达到IsNavigationTarget,这告诉我RegionManager根本不查找现存的视图。那么为什么我们在这里有两种不同的行为,取决于我注册我的导航视图的名称? 我是否错误当我认为当两个名称相同时应用的行为应该是唯一的行为,因为所有其他方案仍然可以使用提到的附加属性创建?

史蒂夫

回答

1

您注册在容器中的一些名称的视图(模型)。然后可以根据注册名称创建视图(模型)的实例。这允许RequestNavigate创建视图(模型)并根据注册名称激活它。

但是,当RequestNavigate正在检查目标视图的可能存在实例(并可能请求IsNavigationTarget)的区域时,它必须处理该区域中视图(模型)的实例。他们的注册名称不可用 - 只有容器知道他们。因此,RequestNavigate假定注册名称是视图类型的Name或FullName。

因此,如果你想拥有所有的功能,你应该在他们的类型名称下注册视图(模型)。有一个方便的方法来做到这一点 - RegisterTypeForNavigation。