PRISM WPF - 导航每次都会创建新视图
我在 WPF 中使用 PRISM 4 导航 API 和 Unity。我有一个树视图,它启动一个 RequestNavigate 并传入所选树节点的 ID (GUID)。
_regionManager.RequestNavigate(RegionNames.DetailRegion,
ViewNames.SiteView + "?ID=" + site.ID);
在我的模块中,我已经注册了视图/视图模型,如下所示:
_container.RegisterType<SiteDetailsViewModel>();
_container.RegisterType<object, SiteDetailsView>(ViewNames.SiteView);
当我从树视图中选择不同的节点时,DetailsRegion 按预期显示SiteDetailsView,但是当我喜欢导航回同一节点,创建一个新的视图/视图模型。
我尝试在 IsNavigationTarget(NavigationContext navigationContext)
处中断,但似乎永远不会调用此方法。
我哪里出错了?提前致谢。
I'm using PRISM 4 Navigation API with Unity in WPF. I have a tree-view that initiates a RequestNavigate passing in the selected tree node's ID (GUID).
_regionManager.RequestNavigate(RegionNames.DetailRegion,
ViewNames.SiteView + "?ID=" + site.ID);
In my module, I have registered the view/view-model like so:
_container.RegisterType<SiteDetailsViewModel>();
_container.RegisterType<object, SiteDetailsView>(ViewNames.SiteView);
When I select different nodes from the tree view, the DetailsRegion displays the SiteDetailsView as expected, but when I like to navigate back to the same node, a new view/view-model is created.
I tried to break at IsNavigationTarget(NavigationContext navigationContext)
but this method appears to never be called.
Where have i gone wrong? Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题出在我从未预料到的地方...调试导航 API 将我引导到 RegionNavigationContentLoader
当我进一步深入代码时,我注意到一个调用:
我注意到这里的命名是将视图与视图模型匹配的关键。
在我的示例中,每个部分的名称是:
当我无意中进行以下更改时:
一切正常。
结论
我通过将视图更改为:
并仍然使用相同的视图名称来注册容器和导航来测试这一点:
这似乎也有效。因此,视图模型的名称似乎与用于导航到该视图的视图名称有着内在的联系。
注意
仅当您将 IoC 和 Unity 与 PRISM 4 导航 API 结合使用时才会出现这种情况。使用 MEF 时似乎不会发生这种情况。
进一步调查
我还知道一些指南 告诉我们使用
typeof(MyView).FullName
在向容器注册视图时...我个人认为这是一个错误。通过使用视图的全名,您可以在视图和任何希望导航到该视图的人之间创建依赖关系...
The problem was in such a place that I never expected... Debugging the Navigation API lead me to the
RegionNavigationContentLoader
When i stepped further down the code, I noticed a call to:
I noticed that the naming here is key to matching the view to the view-model.
In my example, the name for each part was:
When I inadvertently made the following change:
Everthing worked.
Conclusion
I tested this out by changing my view to:
and still using the same view name to register with the container and navigation:
This seems to work also. So it seems the name of the View-Model is intrinsically linked to the view name used to navigate to that view.
NOTE
This is only when you're using IoC and Unity with the PRISM 4 Navigation API. This doesn't seem to happen when using MEF.
Further Investigation
I am also aware that some guides have told us to use the
typeof(MyView).FullName
when registering the view with the Container...I personally think this is a mistake. By using the view's full name, you are creating a depending between the view and any one who wishes to navigate to that view...
View 和 ViewModel 的注册是问题所在。如果只有一种视图,您必须使用不同的生命周期管理器。如果不指定生命周期管理器,则使用 TransientLifetimeManager ,它总是在解析时返回一个新实例。如果只有一个实例,您必须使用 ContainerControlledLifetimeManager 或 HierarchicalLifetimeManager:
The registration of the View and the ViewModel is the problem. To have only one view you have to use a different lifetime manager. Without specifying a lifetime manager the
TransientLifetimeManager
is used which always returns a new instance on resolve. To have only one single instance you have to use theContainerControlledLifetimeManager
or theHierarchicalLifetimeManager
: