2016-12-04 66 views
0

TL;博士導航問題在UWP

我有3頁MainPage.xamlBlankPage1.xamlBlankPage2.xamlButtonMainPageBlankPage1導航到BlankPage1BlankPage2分別。我啓用了系統後退按鈕,以便我可以回到上一頁。

ButtonMainPage定位到BlankPage1Button輕按BlankPage1導航到BlankPage2點擊。這工作正常。

問題:當我點擊Back ButtonBlankPage2它可以追溯到BlankPage。現在當我點擊ButtonBlankPage1它會去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; 
      } 
     } 
    } 
} 

回答

3

每次你導航到一個頁面時, OnNavigatedTo方法正在調用,你是reg正在爲BackRequested事件處理新的處理程序,這意味着當您按下後退按鈕時它將執行多次。您應該在每個頁面的OnNavigatedFrom方法中取消訂閱該事件。

設置Handled = true並不意味着該事件的其他訂閱將不會被執行,它只是意味着:

如果作爲處理你沒有標記的情況下,系統決定是否可以離開從應用程序(在移動設備系列上)或忽略事件(在桌面設備系列上)。

1

從@Decade月球答案構建,我建議你甚至可以集中邏輯到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;    
} 

每次框架導航,後退按鈕的可見性將自動更新。