使用 NavigationView 控件,如何从后面的代码导航?

With a NavigationView control, how can I navigate from the code behind?

是否可以从 NavigationView 中的代码隐藏进行导航? 如果我是 NavigationView 框架中的一页,并且我想离开该页面并显示另一个有效页面,这是否可能。我的项目不是 MVVM 结构。感谢您的帮助。

这是我的 NavigationView:

<NavigationView x:Name="MasterNavigation"
                Header="Main"
                ItemInvoked="MasterNavigation_ItemInvoked" 
                PaneTitle="Menu"
                IsBackButtonVisible="Collapsed"
                IsSettingsVisible="False"
                PaneDisplayMode="Auto"
                OpenPaneLength="200"
                IsTabStop="True">
    
    <NavigationView.MenuItems>

        <NavigationViewItem Icon="Home"       Content="Home"                 Tag="home" IsSelected="True"/>
        <NavigationViewItem Icon="Globe"      Content="Data Collection"      Tag="datacollection"/>
        <NavigationViewItem Icon="Globe"      Content="Data Collection (v2)" Tag="collectdata"/>
        <NavigationViewItem Icon="Document"   Content="Goals"                Tag="goals"/>
        <NavigationViewItem Icon="Manage"     Content="Approvals"            Tag="approvals"/>
        <NavigationViewItem Icon="Print"      Content="Reports"              Tag="reports"/>
        <NavigationViewItem Icon="Admin"      Content="Admin"                Tag="admin"/>
        <NavigationViewItem Icon="PostUpdate" Content="Metric Staging"       Tag="metricstaging"/>
        <NavigationViewItem Icon="PostUpdate" Content="Ref Metric Main"      Tag="refmetricmain"/>
        <!--<NavigationViewItem Icon="Calculator" Content="Dashboard" Tag="dashboard" />-->

    </NavigationView.MenuItems>
    
    <Frame x:Name="MasterContentFrame" Margin="0,0,0,0"/>

</NavigationView>

这是我用来通过 UI 进行导航的代码:

        private void MasterNavigation_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
        {
            if (args.IsSettingsInvoked)
            {
                MasterContentFrame.Navigate(typeof(pageSettings));
            }
            else
            {
                // find NavigationViewItem with Content that equals InvokedItem
                NavigationViewItem item = sender.MenuItems.OfType<NavigationViewItem>().First(x => (string)x.Content == (string)args.InvokedItem);
                NavView_Navigate(item);
            }
        }

        private void NavView_Navigate(NavigationViewItem item)
        {
            switch (item.Tag)
            {
                case "home":
                    MasterContentFrame.Navigate(typeof(pageHome));
                    MasterNavigation.Header = item.Content;
                    break;

                case "datacollection":
                    MasterContentFrame.Navigate(typeof(pageDataCollection));
                    MasterNavigation.Header = item.Content;
                    break;

                case "collectdata":
                    MasterContentFrame.Navigate(typeof(PageCollectMetricData));
                    MasterNavigation.Header = item.Content;
                    break;

                case "goals":
                    MasterContentFrame.Navigate(typeof(pageGoals));
                    MasterNavigation.Header = item.Content;
                    break;

                case "approvals":
                    MasterContentFrame.Navigate(typeof(pageComments));
                    MasterNavigation.Header = item.Content;
                    break;

                case "reports":
                    MasterContentFrame.Navigate(typeof(pageReports));
                    MasterNavigation.Header = item.Content;
                    break;

                case "admin":
                    MasterContentFrame.Navigate(typeof(pageAdmin));
                    MasterNavigation.Header = item.Content;
                    break;

                case "metricstaging":
                    MasterContentFrame.Navigate(typeof(pageMetricStaging));
                    MasterNavigation.Header = item.Content;
                    break;

                case "refmetricmain":
                    MasterContentFrame.Navigate(typeof(pageRefMetricMain));
                    MasterNavigation.Header = item.Content;
                    break;
            }
        }

我在 'Metric Staging' 页面上有一个按钮,如果单击该按钮,我希望它在 MasterContentFrame 中打开 'Data Collection' 页面。

这里是按钮事件代码,在'Metric Staging'页面点击按钮时触发:

private void ButtonListViewEdit_Click(object sender, RoutedEventArgs e)
{
    Debug.WriteLine($"PAGE METRIC STAGING: BUTTON WAS CLICKED");
    // Below are my attempts to implement 'code-behind' navigation 
    //MetricReporting.MainWindow MasterContentFrame.Navigate(typeof(pageDataCollection));
    //MasterNavigation.Header = "Data Collection";
    //var navigation = (Application.Current as App).MasterNavigation;
}

您可以将 window 中 Frame 元素的 x:FieldModifier 属性设置为 internalpublic 以便能够访问 Frame 来自另一个 class:

<Frame x:Name="MasterContentFrame" x:FieldModifier="internal" Margin="0,0,0,0"/>

同时更改 App.xaml.csm_window 字段的修饰符:

internal Window m_window;

然后您可以从 Page 中的事件处理程序访问 Frame,如下所示:

private void ButtonListViewEdit_Click(object sender, RoutedEventArgs e)
{
    MainWindow window = (App.Current as App)?.m_window as MainWindow;
    if (window != null)
    {
        window.MasterContentFrame.Navigate(typeof(typeof(pageDataCollection)));
    }
}