几个月前我发布了类似的问题使用 Prism 和 IsNavigationTarget 处理嵌套视图,可能返回 false,我仍然不确定正确的方法是什么。
假设你有一个视图A,在这个视图A中你声明了一个区域A,然后你在这个区域A中注入了一个视图B。同样,在视图B中你注册了区域B,然后你在这个区域中注入了一个视图C B、如下图所示:
在 ViewS 的 ViewModel 中,我有一个方法 SetUp SubViews() ,我在其中调用:
_regionManager.RequestNavigate("regionA", "ViewB", NavigationCallback);
视图 B 的 ViewModelB 实现 INavigationAware。因此,在 OnNavigateTo() 方法中我调用:
_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}" />
现在,当我第一次在 ViewModel 上调用 SetUp SubViews() 方法时,一切都很好。当我第二次调用它时,我看到了异常:
具有给定名称的区域已注册
...
我需要的是有一种方法可以在每次需要时从头开始重新创建视图视图模型对。似乎当视图被处置时,棱镜不会删除在已删除视图中声明的区域。请问社区和棱镜开发者,如何正确地做到这一点?
当前的解决方案并不令人满意,这就是我所做的:
步骤 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);}
同样,我必须从 View 上的区域区域中删除 ViewS 有 Region.RemoveAll() 是关键行。)
Step3 - 我没有在 viewB 和 viewC 上实现 IRegionMemberLifetime 接口。
它有效,但看起来不正确。
附:我也尝试了作用域管理器,但我不知道如何将新创建的作用域管理器传播到视图模型,因为它们是自动创建的,如果我通过构造函数解决它,我会得到主全局管理器而不是作用域。
Thanks.