首页 > 解决方案 > 如何在导航历史记录中查找 WPF Page 以防止再次打开该页面

问题描述

如何确定 WPF 页面是否仍在 WPF 框架的导航历史记录中,然后导航回该页面?

概括:

我的 WPF 应用程序使用一个 MainWindow,其中包含两个 Frame,一个用于菜单布局,另一个用于显示内容。我正在使用 MVVM 模式,内容显示为 WPF 页面作为视图,每个视图/页面后面的代码尽可能少。

内容框架(以红色显示)有一个可见的 NavigationUI。 在此处输入图像描述

XAML:

在此处输入图像描述

这是创建 WPF 页面并将其从静态帮助程序类显示在主窗口中的典型代码:

public static void ShowPeriodicTable()
{
  var page = new Views.PeriodicTable();
  (Application.Current.MainWindow as MainWindow).ContentArea.Navigate(page);
}

即使它已经加载,此代码也会一遍又一遍地加载相同的页面。

在创建和导航到页面之前,我进行了以下更改以检测当前页面是否显示在 MainWindow.ContentArea(框架)中。

public static void ShowPeriodicTable()
    {                   
        var currentPage = ((DRC_SQLITE.MainWindow)Application.Current.MainWindow).ContentArea.Content;
        if (currentPage == null || (currentPage != null && currentPage.GetType().Name != "PeriodicTable"))
        {
            var page = new Views.PeriodicTable();
            (Application.Current.MainWindow as MainWindow).ContentArea.Navigate(page);
        }
    }

问题:

如何检测即将打开的页面是否存在于导航历史中但不是框架中的当前页面。在下图中,settingPage 被打开了两次。这是我想要消除的场景,以更好地管理应用程序的内存使用情况。

在此处输入图像描述

标签: wpfmvvm

解决方案


页面很少用于商业应用程序。据我了解,它们实际上是为 xbap 设计的(浏览器中的 wpf )。将用户控件托管在内容控件中更为常见。在这种情况下,有两种常用的替代方案

1) 先查看。保存按类型键入的用户控件字典。 https://gallery.technet.microsoft.com/WPF-Navigation-Basic-Sample-11f10c74

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Navigate(typeof(HomeView));
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)e.OriginalSource;
            Navigate(btn.Tag as Type);
        }

        private void Navigate (Type viewType)
        {
            UserControl uc;
            if (Views.ContainsKey(viewType))
            {
                uc = Views[viewType];
            }
            else
            {
                uc = (UserControl)Activator.CreateInstance(viewType);
                Views[viewType] = uc;
            }
            NavigationParent.Content = uc;
        }
        private Dictionary<Type, UserControl> Views = new Dictionary<Type, UserControl>();
    }

这一点的支持者指出,导航可以说是一种视图责任。

2)首先查看模型。

将 contentcontrol 的内容绑定到 mainwindowviewmodel 中的属性。将其切换为每个视图的视图模型,并将模板切换为用户控件。然后,您通过为每个视图保留对视图模型的引用来控制保留状态。

如果你真的想坚持你所拥有的,那么 Frame.BackStack 就是日志中条目的集合。您可以迭代它并检查每个对象的类型。我认为它实际上是对页面的引用。我从未在商业应用程序中看到过这种方法。


推荐阅读