Wpf 重新导航到多视图区域中的特定视图
我正在开发一个利用MicrosoftPrism框架的WPF应用程序。应用程序的一个方面是“模态”区域,它可以容纳覆盖整个窗口的任意数量的模态窗口。随着更多视图导航到该区域,每个窗口向右滑动,以允许新窗口占据屏幕中心。这里有一个更直观的解释: 当“模式”区域包含单个视图时: 将其他视图添加到区域时: 添加多个视图时: 我使用一个自定义控件来管理其子对象的动画和显示。下面是控件的自定义Wpf 重新导航到多视图区域中的特定视图,wpf,prism,region,regionadapter,Wpf,Prism,Region,Regionadapter,我正在开发一个利用MicrosoftPrism框架的WPF应用程序。应用程序的一个方面是“模态”区域,它可以容纳覆盖整个窗口的任意数量的模态窗口。随着更多视图导航到该区域,每个窗口向右滑动,以允许新窗口占据屏幕中心。这里有一个更直观的解释: 当“模式”区域包含单个视图时: 将其他视图添加到区域时: 添加多个视图时: 我使用一个自定义控件来管理其子对象的动画和显示。下面是控件的自定义RegionAdapter的Adapt方法的外观: protected override void Adapt
RegionAdapter
的Adapt
方法的外观:
protected override void Adapt(IRegion region, ModalContainer regionTarget)
{
region.ActiveViews.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler((o, e) =>
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
foreach(FrameworkElement element in e.NewItems)
{
regionTarget.AddChild(element);
}
}
else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
foreach (FrameworkElement element in e.OldItems)
{
regionTarget.RemoveChild(element);
}
}
});
}
我的问题是:导航回早期窗口的最佳方式是什么?现在,我知道触发上面的RemoveChild
方法的唯一方法是从区域中显式删除视图,这要求我在某个地方保留区域中当前所有视图的列表:
// to remove the most recently added view from the region
_regionManager.Regions["ModalRegion"].Remove(addedViews.Pop());
理想情况下,我可以使用Prism的“日志记录”概念向后导航,但我在我的RegionaAdapter
中看不到一种方式来响应已在该区域中的视图被重新导航到的情况
如有任何提示,将不胜感激
编辑
我通过遵循GOstrowsky的建议(参见接受答案中的注释)实现了这一功能-我更改了我的区域适配器,以便仅在区域中维护一个活动视图(当前位于屏幕中心的视图)。然后,我可以通过myRegion.activeview.FirstOrDefault()
将该视图作为删除的目标
又一次编辑
此后,我再次更改了此实现,因为我们需要能够删除该区域当前的任何视图,而不仅仅是最后一个视图。有关详细信息,请参阅已接受的答案。如果您希望局部导航回以前的视图,则在从该视图导航时不应将其从区域中删除 相反,您可以通过OnNavigatedFrom()方法将其停用。然后,使用导航日志返回 关于RegionaAdapter控件,您可以修改它,以便它可以处理视图激活和取消激活。例如,您可以从每个ViewModelOnNavigatedFrom()和OnNavigatedTo()发布取消/激活更改的事件,并通过订阅自定义控件并对每个事件执行相应的任务,在自定义控件上处理这些事件 您可以在以下MSDN Prism Guide章节中找到有关导航和事件聚合的更多信息:
关于。最初,我解决了这个问题,只允许单个区域处于活动状态,这保证了删除该区域当前处于活动状态的视图始终会删除当前位于屏幕中心的视图。然而,从那时起,我们需要能够从该区域删除任何视图,而不仅仅是第一个视图。为此,我意识到可以将
Region.Views
属性转换为列表
,然后通过索引进行访问:
List<object> allViews = modalRegion.Views.ToList<object>();
List allview=modalRegion.Views.ToList();
我对这个解决方案有点不舒服,因为
IViewsCollection
定义继承自IEnumerable
,而不是IList
;从技术上讲,我可以得到一个定制的IViewsCollection
,它不能转换为IList
。。。。但在短期内,我将用这个来运行。对不起,我不清楚。当我说我想“导航回以前的视图”时,我指的是仍然存在于区域中的视图——屏幕右侧的一个视图。一旦取消模式窗口(在屏幕左侧设置动画),我就不再需要重新导航到视图的同一个实例。您可以将居中视图设置为区域中唯一的活动视图,而不是在区域中保留视图列表。左侧的视图可以将IsActive属性设置为false。因此,左侧的视图仍将显示,当删除居中视图时,可以使用“Region.ActiveViews.firstOrDefault()”获得它。以下导航视图将在OnNavigatedTo()方法中将其IsActive属性设置为true。正如您所建议的,我只通过在区域中维护单个活动视图来跟踪要删除的视图。谢谢你的帮助!