我使用Prism 5.0,并且在配置它以重用现有视图时遇到问题。每当调用IRegionManager.RequestNavigate(string regionName, Uri source)
时,它将创建一个新视图,而不是使用先前创建的视图。奇怪的是,CLRProfiler还指出Prism的区域管理器持有引用所有先前创建的视图实例,导致内存泄漏。阻止棱镜创建导航新视图
我的视图模型实现了INavigationAware
,并在IsNavigationTarget()
中返回true
,但该方法从未被调用过。我试图在视图上实现它,并得到相同的结果。
作为测试,我在视图上实现了IActiveAware
,这表明一旦我导航到另一个视图(我不确定这是否相关),它就会停用。
我发现这个问题:PRISM WPF - Navigation creates new view every time但我的V-VM命名约定匹配那些答案(我使用AutoFac,顺便说一句)。
我只找到了解决方法:在视图模型的INavigationAware.OnNavigatedFrom()
实现中使用NavigationContext.NavigationService.Region.Remove()
从区域中删除活动视图。当我这样做时,Prism的区域经理会发布对该视图的引用。这有效,但在需要时总是重新创建视图似乎效率低下。
几乎所有关于SO的相关问题都要求如何在导航事件上创建新视图,所以我假设默认行为是视图被重用。我需要指针。
编辑
我们使用AutoFac的AutofacExtensions.RegisterTypeForNavigation<T>(this ContainerBuilder builder, string name = null)
注册的意见。我们确实使用IRegionManager.RequestNavigate()
在视图之间导航。在ViewModels上实现了INavigationAware
。但是,虽然调用了INavigationAware.OnNavigatedTo()
和OnNavigatedFrom()
,但从未调用IsNavigationTarget()
(即使视图实现了INavigationAware
,也不调用后者)。
我可以通过在视图的ctor中设置断点来检测到新视图。 CLRProfiler堆转储还显示区域管理器拥有多次导航到的视图的实例。 ViewModels只创建一次,因为它们是以AutoFac作为单一实例注册的。
作为一项临时措施,我们制定了意见实施IRegionMemberLifetime
,其中KeepAlive
返回false
。这不是非常有效,因为每次需要时都会重新创建视图,但它会阻止区域经理坚持以前的视图。
您需要使用IRegionMemberLifetime和KeepAlive属性。 –
@AyyappanSubramanian如果视图实现IRegionMemberLifetime,并且KeepAlive返回true,则区域管理器会保留对视图的引用,但会在导航到该视图时创建一个新视图(如果该视图未实现IRML,则该视图必须是默认视图)。如果KeepAlive返回false,则该视图将被丢弃,因此需要重新创建。我的问题是如何让Prism重用原始视图,所以这不是一个解决方案。 – Drew
我目前有同样的问题,虽然不是我所有的意见。它似乎是任何低于特定页面,这是导致我的问题。 – user3265613