几个月前我发布了类似的问题使用带有 IsNavigationTarget 的 Prism 的嵌套视图可以返回 false,我仍然不确定什么是正确的方法。
假设你有一个视图 A,在这个视图 A 中你已经声明了一个区域 A,然后你将一个视图 B 注入到这个区域 A 中。类似地,在视图 B 中你已经注册了一个区域 B,然后你将一个视图 C 注入到这个区域中B. 如下图所示:
在 ViewA 的 ViewModelA 中,我有一个方法 SetUpSubViews() 我在其中调用:
_regionManager.RequestNavigate("regionA", "ViewB", NavigationCallback);
View B 的 ViewModelB 实现 INavigationAware。所以在 OnNavigatedTo() 方法中我调用:
_regionManager.RequestNavigate("regionB", "ViewC", NavigationCallback);
View C 的 ViewModelC 也实现了 INavigationAware。
现在,我在 IsNavigationTarget() 方法中同时拥有 ViewModelB 和 ViewModelC :
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return false;
}
这意味着我想在每次导航此视图时创建新视图。
ViewB 和 ViewC 都实现了 IRegionMemberLifetime 接口,我在其中设置:
#region IRegionMemberLifetime
public bool KeepAlive => false;
#endregion
这意味着我不想重用视图,我希望它被处理掉。
视图中的区域声明如下:
<ContentControl prism:RegionManager.RegionName="{x:Static localRegions:LocalRegions.RegionB}" />
现在,当我第一次在 ViewModelA 上调用 SetUpSubViews() 方法时,一切都很好。第二次调用它时,我看到了异常:
具有给定名称的区域已注册...
我需要的是有一种方法可以在每次需要时从头开始重新创建视图<->视图模型对。似乎在处理视图时,棱镜不会删除在已删除视图中声明的区域。向社区和棱镜开发人员提问,如何以正确的方式做到这一点?
当前的解决方案并不令人满意,这就是我要做的:第 1 步 - 我在 INavigationAware 部分的 ViewModelB 和 ViewModelC 中设置
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
这向 prism 发出信号不要创建新视图,并且可能还意味着如果在视图中找到任何区域,则不要在区域管理器中注册它。
第 2 步 - 当我需要向区域注入视图时,我手动删除旧视图并创建新视图。所以我的 SetUpSubViews() 方法如下所示:
protected void SetUpSubViews(){
//get region by name
var region = _regionManager.Regions["regionA"];
// push to remove all views from the region
region.RemoveAll();
// navigate to view
_regionManager.RequestNavigate("regionA", "ViewB", NavigationCallback);}
同样,我必须从 ViewB 上的区域 regionB 中删除 ViewC。(这里是 region.RemoveAll() 是关键行。)
Step3 - 我没有在 viewB 和 viewC 上实现 IRegionMemberLifetime 接口。
它有效,但看起来不正确。
PS我也尝试过作用域管理器,但我不知道如何将新创建的作用域管理器传播到视图模型,因为它们是自动创建的,如果我通过构造函数解决它,我会得到主全局管理器而不是作用域。
谢谢。