0

我正在开发一个使用 Microsoft Prism 框架的 WPF 应用程序。该应用程序的一个方面是一个“模态”区域,它可以容纳覆盖整个窗口的任意数量的模态窗口。随着更多视图被导航到该区域,每个窗口都会向右滑动以允许新窗口占据屏幕的中心。这是一个更直观的解释:

当“模态”区域包含单个视图时:

当。。。的时候

当另一个视图添加到区域时:

当另一个视图添加到区域时

当添加更多视图时:

当添加更多视图时

我使用一个自定义控件来管理其子项的动画和显示。下面是控件的 custom方法RegionAdapterAdapt样子:

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());

RegionAdapter理想情况下,我将能够使用 Prism 的“日志”概念向后导航,但是当重新导航到该区域中的视图时,我看不到响应的方式。

任何提示将不胜感激。

编辑

通过遵循 GOstrowsky 的建议(请参阅已接受答案中的评论),我能够实现此功能 - 我将区域适配器更改为仅在该区域中维护一个活动视图(当前位于屏幕中心的视图)。然后我可以通过myRegion.ActiveViews.FirstOrDefault().

另一个编辑

此后,我再次更改了此实现,因为我们需要能够删除当前在该区域中的任何视图,而不仅仅是最后一个。有关详细信息,请参阅接受的答案。

4

2 回答 2

1

如果您偶尔想要导航回以前的View,则在从该区域导航时不应将其从该区域中删除。

相反,您可以通过OnNavigatedFrom()方法将其停用。然后,使用NavigationJournal导航回来。

关于您的RegionAdapter控件,您可以对其进行修改,以便它可以处理视图激活和停用。例如,您可以从每个ViewModel OnNavigatedFrom()OnNavigatedTo()发布De/ActivationChanged事件,并通过订阅它并对每个事件执行相应的任务来处理自定义控件上的这些事件。

您可以在以下MSDN Prism 指南章节中找到有关导航和事件聚合的更多信息:

我希望这会有所帮助,问候。

于 2014-03-17T18:20:56.077 回答
0

最初,我通过只允许单个区域处于活动状态来解决这个问题,这保证了删除该区域的当前活动视图总是会删除当前位于屏幕中心的视图。但是,从那时起,我们需要能够从该区域中删除任何视图,而不仅仅是第一个。为了做到这一点,我意识到可以将Region.Views属性转换为 aList然后通过索引访问:

List<object> allViews = modalRegion.Views.ToList<object>();

我对这个解决方案有点不舒服,因为IViewsCollection定义继承自IEnumerable, 而不是IList; IViewsCollection从技术上讲,我可以得到一个不能被投射到……的习惯,IList但在短期内我会用这个来运行。

于 2014-03-26T19:53:47.337 回答