PRISM WPF - 导航每次都会创建新视图
Posted
技术标签:
【中文标题】PRISM WPF - 导航每次都会创建新视图【英文标题】:PRISM WPF - Navigation creates new view every time 【发布时间】:2011-09-11 10:38:07 【问题描述】:我在 WPF 中使用带有 Unity 的 PRISM 4 Navigation API。我有一个树视图,它启动一个 RequestNavigate,传入所选树节点的 ID (GUID)。
_regionManager.RequestNavigate(RegionNames.DetailRegion,
ViewNames.SiteView + "?ID=" + site.ID);
在我的模块中,我已经像这样注册了视图/视图模型:
_container.RegisterType<SiteDetailsViewModel>();
_container.RegisterType<object, SiteDetailsView>(ViewNames.SiteView);
当我从树视图中选择不同的节点时,DetailsRegion 会按预期显示 SiteDetailsView,但是当我想导航回同一个节点时,会出现一个新视图/view-model 已创建。
我试图在IsNavigationTarget(NavigationContext navigationContext)
中断,但这个方法似乎永远不会被调用。
我哪里出错了?提前致谢。
【问题讨论】:
【参考方案1】:问题出在我没想到的地方...调试导航 API 将我带到RegionNavigationContentLoader
public object LoadContent(IRegion region, NavigationContext navigationContext)
当我进一步降低代码时,我注意到一个调用:
protected virtual IEnumerable<object> GetCandidatesFromRegion(
IRegion region,
string candidateNavigationContract)
我注意到这里的命名是将视图与视图模型匹配的关键。
在我的示例中,每个部分的名称是:
public class SiteDetailsViewModel ... // ViewModel
public class SiteDetailsView ... // View
ViewNames.SiteView = "SiteView" // ViewName constant
当我无意中做了以下更改时:
ViewName.SiteView = "SiteDetailsView"
一切正常。
结论
ViewModel 的名称必须以 和你以前的名字一样 确定您的观点。
我通过将视图更改为:
public class MyView ...
并且仍然使用相同的视图名称来注册容器和导航:
_container.RegisterType<object, MyView>(ViewNames.SiteView);
...
_regionManager.RequestNavigate(RegionNames.DetailRegion,
ViewNames.SiteView + "?ID=" + site.ID);
这似乎也有效。因此,View-Model 的名称似乎与用于导航到该视图的视图名称有内在联系。
注意
仅当您将 IoC 和 Unity 与 PRISM 4 Navigation API 一起使用时。使用 MEF 时似乎不会发生这种情况。
进一步调查
我也知道一些guides 告诉我们在向容器注册视图时使用typeof(MyView).FullName
...
_container.RegisterType<object, MyView>(typeof(MyView).FullName);
我个人认为这是一个错误。通过使用视图的全名,您可以在视图和希望导航到该视图的任何人之间创建依赖关系...
_regionManager.RequestNavigate(RegionNames.DetailRegion,
typeof(MyView).FullName + "?ID=" + site.ID);
【讨论】:
是的,奇怪的行为,我在 cmets 中找到了这个问题的信息compositewpf.codeplex.com/workitem/7468?PendingVoteId=7468【参考方案2】:View 和 ViewModel 的注册是个问题。要只有一个视图,您必须使用不同的生命周期管理器。在不指定生命周期管理器的情况下,使用TransientLifetimeManager
,它总是在解析时返回一个新实例。要只有一个实例,您必须使用ContainerControlledLifetimeManager
或HierarchicalLifetimeManager
:
_container.RegisterType<SiteDetailsViewModel>(new ContainerControlledLifetimeManager());
_container.RegisterType<object, SiteDetailsView>(ViewNames.SiteView, new ContainerControlledLifetimeManager());
【讨论】:
以上是关于PRISM WPF - 导航每次都会创建新视图的主要内容,如果未能解决你的问题,请参考以下文章