我正在开发一个使用Microsoft Prism框架的WPF应用程序。该应用程序的一个方面是“模态”区域,其可以保持覆盖整个窗口的任何数量的模态窗口。随着更多视图导航到该区域,每个窗口向右滑动以允许新窗口占据屏幕的中心。这是一个更直观的解释:
当“模态”区域包含单个视图时:
当另一个视图添加到该区域时:
当添加更多视图时:
我使用自定义控件来管理动画和显示其子项。以下是控件的自定义RegionAdapter
的{{1}}方法的样子:
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
理想情况下,我可以使用Prism的“日记”概念向后导航,但我没有看到// to remove the most recently added view from the region
_regionManager.Regions["ModalRegion"].Remove(addedViews.Pop());
中的某种方式可以响应已经在该区域中的视图重新导航到的时间。
任何提示都会非常感激。
修改
我可以通过遵循GOstrowsky的建议来实现此功能(请参阅接受的答案中的注释) - 我将区域适配器更改为仅在区域中维护单个活动视图(当前位于中心的视图屏幕)。然后,我可以通过RegionAdapter
定位该视图以进行删除。
另一个编辑
我已经再次更改了此实现,因为我们需要能够删除当前在该区域中的任何视图,而不仅仅是最后一个。有关详细信息,请参阅接受的答案。
答案 0 :(得分:1)
如果您想要导航回到之前的 View ,则在导航时不应将其从 Region 中删除。
相反,您可以从 OnNavigatedFrom() 方法停用它。然后,使用 NavigationJournal 进行导航。
关于 RegionAdapter 控件,您可以对其进行修改,以便它可以处理查看激活和取消激活。例如,您可以从每个 ViewModel < 发布 De / ActivationChanged 事件strong> OnNavigatedFrom() 和 OnNavigatedTo() ,并通过订阅和执行自定义控件来处理这些事件每个事件的相应任务。
您可以在以下 MSDN棱镜指南章节中找到有关导航和事件聚合的更多信息:
我希望这有帮助, 问候。
答案 1 :(得分:0)
最初,我通过仅允许单个区域处于活动状态来解决了这个问题,这保证了移除区域的当前活动视图总是移除当前位于屏幕中心的视图。但是,从那时起,我们需要能够从区域中移除任何视图,而不仅仅是第一个。为了实现这一点,我意识到Region.Views
属性可以强制转换为List
,然后通过索引访问:
List<object> allViews = modalRegion.Views.ToList<object>();
我对这个解决方案有点不舒服,因为IViewsCollection
定义继承自IEnumerable
,而不是IList
;从技术上讲,我可以交给一个不能投放到IViewsCollection
的自定义IList
....但是在短期内我会用这个来运行。