【问题标题】:Navigation Issue in UWPUWP 中的导航问题
【发布时间】:2016-12-04 00:47:36
【问题描述】:

tl;dr

我有 3 个页面 MainPage.xamlBlankPage1.xamlBlankPage2.xamlButtonMainPageBlankPage1 上分别导航到 BlankPage1BlankPage2。我启用了系统返回按钮,以便我可以返回上一页。

Button 点击MainPage 导航到BlankPage1Button 点击BlankPage1 导航到BlankPage2。这很好用。

问题:当我在BlankPage2 上点击Back Button 时,它会返回到BlankPage。现在,当我在BlankPage1 上点击Button 时,它会转到BlankPage2,但是当我点击Back Button,而不是转到BlankPage1 时,它会直接导航到MainPage

下面是我的代码。

MainPage.xaml

<Page
    x:Class="App2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App2"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Button Content="GoTo Page 1" HorizontalAlignment="Center" VerticalAlignment="Center" Tapped="Button_Tapped"/>
    </Grid>
</Page>

MainPage.xaml.cs

using Windows.UI.Xaml.Controls;

namespace App2
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void Button_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
        {
            Frame.Navigate(typeof(BlankPage1));
        }
    }
}

BlankPage1.xaml

<Page
    x:Class="App2.BlankPage1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App2"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Button Content="GoTo Page 2" HorizontalAlignment="Center" VerticalAlignment="Center" Tapped="Button_Tapped"/>
    </Grid>
</Page>

BlankPage1.xaml.cs

using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace App2
{
    public sealed partial class BlankPage1 : Page
    {
        public BlankPage1()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (Frame.CanGoBack)
            {
                SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
                SystemNavigationManager.GetForCurrentView().BackRequested += (s, a) =>
                {
                    if (Frame.Content.GetType() == typeof(BlankPage1))
                    {
                        if (Frame.CanGoBack)
                        {
                            Frame.GoBack();
                            a.Handled = true;
                        }
                    }
                };
            }
            else
            {
                SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
            }
        }

        private void Button_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
        {
            Frame.Navigate(typeof(BlankPage2));
        }
    }
}

BlankPage2.xaml

<Page
    x:Class="App2.BlankPage2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App2"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="Final Page" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
</Page>

BlankPage2.xaml.cs

using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace App2
{
    public sealed partial class BlankPage2 : Page
    {
        public BlankPage2()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (Frame.CanGoBack)
            {
                SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
                SystemNavigationManager.GetForCurrentView().BackRequested += (s, a) =>
                {
                    if (Frame.Content.GetType() == typeof(BlankPage2))
                    {
                        if (Frame.CanGoBack)
                        {
                            Frame.GoBack();
                            a.Handled = true;
                        }
                    }
                };
            }
            else
            {
                SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
            }
        }
    }
}

【问题讨论】:

    标签: navigation uwp windows-10


    【解决方案1】:

    每次导航到页面时,都会调用 OnNavigatedTo 方法,并且您正在为 BackRequested 事件注册一个新的处理程序,这意味着当您按下返回按钮时它会执行多次。您应该在每个页面的 OnNavigatedFrom 方法中取消订阅该事件。

    设置Handled = true并不意味着该事件的其他订阅不会被执行,它只是意味着:

    如果您未将事件标记为已处理,系统将决定是离开应用程序(在移动设备系列上)还是忽略该事件(在桌面设备系列上)。

    【讨论】:

      【解决方案2】:

      根据@Decade Moon 的回答,我建议您甚至可以将逻辑集中到App 类中,以便于管理和更简洁的Page 代码隐藏。

      将以下行添加到App.OnLaunched 方法:

      SystemNavigationManager.GetForCurrentView().BackRequested += App_BackRequested;
      

      并像这样实现处理程序:

      private void App_BackRequested(object sender, BackRequestedEventArgs e)
      {
          var frame = ( Frame )Window.Current.Content;
          if ( frame.CanGoBack )
          {
              frame.GoBack();
              e.Handled = true;
          }
      }
      

      我们抓取当前窗口的框架并检查是否可以返回。如果可能,我们会处理事件并导航。这样做的好处是,您现在可以删除所有页面上的所有 BackRequested 相关操作。

      您也可以对AppViewBackButtonVisibility 做类似的事情:在OnLaunched 的末尾添加以下内容:

      rootFrame.Navigated += RootFrame_Navigated;
      

      现在将处理程序实现为:

      private void RootFrame_Navigated(object sender, NavigationEventArgs e)
      {
          var frame = (Frame)Window.Current.Content;
          SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
              frame.CanGoBack ? AppViewBackButtonVisibility.Visible :
                                AppViewBackButtonVisibility.Collapsed;            
      }
      

      每次框架导航时,后退按钮的可见性都会自动更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-11-30
        • 2021-07-16
        • 1970-01-01
        • 1970-01-01
        • 2021-12-24
        相关资源
        最近更新 更多