【问题标题】:Re-navigate to a particular view in multi-view region重新导航到多视图区域中的特定视图
【发布时间】:2014-04-21 06:35:00
【问题描述】:

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

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

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

当添加更多视图时:

我使用一个自定义控件来管理其子项的动画和显示。下面是控件的自定义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());

理想情况下,我可以使用 Prism 的“日志”概念向后导航,但在我的 RegionAdapter 中没有看到当重新导航到该区域中的视图时做出响应的方法。

任何提示将不胜感激。

编辑

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

又一次编辑

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

【问题讨论】:

    标签: wpf prism region regionadapter


    【解决方案1】:

    如果您偶尔想要导航回之前的视图,则在导航时不应将其从区域中移除。

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

    关于您的 RegionAdapter 控件,您可以对其进行修改,以便它可以处理 View 激活和停用。例如,您可以从每个 ViewModelPublishDe/ActivationChanged 事件OnNavigatedFrom()OnNavigatedTo(),并通过订阅它并执行每个事件对应的任务。

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

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

    【讨论】:

    • 对不起,我不清楚。当我说我想“导航回较早的视图”时,我的意思是仍然存在于区域中的视图 - 其中一个视图位于屏幕的右侧。一旦模式窗口被关闭(动画离开屏幕左侧),我将不再需要重新导航到视图的同一实例。
    • 您可以使居中的视图成为该区域中唯一的活动视图,而不是保留区域中的视图列表。左侧的视图可以将 IsActive 属性设置为 false。因此,仍然会显示左侧的视图,并且在移除居中的视图时,您可以使用:“Region.ActiveViews.firstOrDefault()”来获取它。以下导航视图将在 OnNavigatedTo() 方法中将其 IsActive 属性设置为 true。
    • 按照您的建议,我最终通过仅在该区域中维护一个活动视图来跟踪要删除的视图。感谢您的帮助!
    【解决方案2】:

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

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

    我对这个解决方案有点不舒服,因为IViewsCollection 定义继承自IEnumerable,而不是IList;从技术上讲,我可以得到一个无法转换为 IList 的自定义 IViewsCollection.... 但在短期内我将使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-14
      相关资源
      最近更新 更多