tl; dr
我有3页MainPage.xaml
,BlankPage1.xaml
,BlankPage2.xaml
,Button
上的CC_4和BlankPage1
分别导航到BlankPage1
和BlankPage2
。我启用了系统返回按钮,以便可以返回上一页。
Button
在MainPage
上点击BlankPage1
,然后Button
点击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;
}
}
}
}
每次导航到页面时,都会调用OnNavigatedTo
方法,并且您正在为BackRequested
事件注册一个新处理程序,这意味着当您按下后面时,它将多次执行按钮。您应该在每个页面的OnNavigatedFrom
中取消订阅该事件。
设置Handled = true
并不意味着无法执行该事件的其他订阅,而只是表示:
如果您不将事件标记为处理的事件,则该系统决定是否远离应用程序(在移动设备系列上)或忽略事件(在台式设备系列上)。
在@decade月亮的答案上构建,我建议您甚至可以将逻辑集中到App
类中,以更容易的可管理性和清洁器Page
COD-BEHINDS。
将以下行添加到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;
}
每次框架导航时,后退按钮的可见性将自动更新。