2011-06-09 65 views
6

我在WPF中使用PRISM 4导航API和Unity。我有一个树视图,它启动一个RequestNavigate传入所选树节点的ID(GUID)。PRISM WPF - 导航每次创建新视图

_regionManager.RequestNavigate(RegionNames.DetailRegion, 
    ViewNames.SiteView + "?ID=" + site.ID); 

以我模块,我已经注册的视图/视图模型像这样:

_container.RegisterType<SiteDetailsViewModel>(); 
_container.RegisterType<object, SiteDetailsView>(ViewNames.SiteView); 

当我选择从树视图的不同节点,则DetailsRegion显示SiteDetailsView如预期的,但是当我喜欢回到同一个节点时,会创建一个新的视图/视图模型。

我试图打破在IsNavigationTarget(NavigationContext navigationContext)但这种方法似乎永远不会被调用。

我哪里出错了?提前致谢。

回答

7

的问题是这样的,我从来没想过的地方......调试导航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" 

寄托都工作过。

结论

视图模型的名称必须与你用来 识别您的看法相同的名称开始 。

我测试了这一点,通过改变我的观点到:

public class MyView { ... } 

,并仍然使用相同的视图名称与容器和导航注册:

_container.RegisterType<object, MyView>(ViewNames.SiteView); 

... 

_regionManager.RequestNavigate(RegionNames.DetailRegion, 
    ViewNames.SiteView + "?ID=" + site.ID); 

这似乎也工作。因此,View-Model的名称似乎与用于导航到该视图的视图名称有内在联系。

注意

这仅仅是当你使用的IoC和Unity与棱镜4导航API。这在使用MEF时似乎不会发生。

进一步调查

我也知道,有些guides告诉我们,使用登记与容器视图时typeof(MyView).FullName ...

_container.RegisterType<object, MyView>(typeof(MyView).FullName); 

我个人认为这是一个错误。通过使用视图的全名,您可以创建视图和任何希望导航到该视图的人...

_regionManager.RequestNavigate(RegionNames.DetailRegion, 
    typeof(MyView).FullName + "?ID=" + site.ID); 
+0

是啊,奇怪的行为,我发现这个信息在这个问题的评论http://compositewpf.codeplex.com/workitem/7468?PendingVoteId=7468 – 2011-09-27 08:00:10

0

视图和ViewModel的注册是问题。要只有一个视图,你必须使用不同的生命期管理器。如果没有指定生命期管理器,则使用TransientLifetimeManager,它总是在解析时返回一个新实例。为了只有一个单一的情况下,你必须使用ContainerControlledLifetimeManagerHierarchicalLifetimeManager

_container.RegisterType<SiteDetailsViewModel>(new ContainerControlledLifetimeManager()); 
_container.RegisterType<object, SiteDetailsView>(ViewNames.SiteView, new ContainerControlledLifetimeManager()); 
+1

这并未解决问题。 – 2011-06-09 23:51:55