navigation - detail - uwp navigate to page
Problema de navegaciĆ³n en UWP (2)
tl; dr
Tengo 3 páginas MainPage.xaml
, BlankPage1.xaml
, BlankPage2.xaml
con Button
en MainPage
y BlankPage1
que navega a BlankPage1
y BlankPage2
Respectively. He habilitado el botón Atrás del sistema para que pueda volver a la página anterior.
Button
Tocar en MainPage
navega a BlankPage1
y Button
Tocar en BlankPage1
navega a BlankPage2
. Esto funciona bien
Problema: cuando BlankPage2
el Back Button
en BlankPage2
, vuelvo a BlankPage
. Ahora, cuando BlankPage1
el Button
en BlankPage1
, BlankPage1
a BlankPage2
pero cuando BlankPage2
el Back Button
, en lugar de ir a BlankPage1
, navega directamente a MainPage
.
A continuación está mi código.
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;
}
}
}
}
Cada vez que OnNavigatedTo
hacia una página, se OnNavigatedTo
método OnNavigatedTo
y estás registrando un nuevo controlador para el evento BackRequested
, lo que significa que se ejecutará varias veces cuando presiones el botón Atrás. Debe darse de baja de ese evento en su método OnNavigatedFrom
de cada página.
Establecer Handled = true
no significa que no se ejecutarán otras suscripciones para ese evento, solo significa:
Si no marca el evento como manejado, el sistema decide si navegará desde la aplicación (en la familia de dispositivos móviles) o ignorará el evento (en la familia de dispositivos de escritorio).
Continuando con la respuesta de @Decade Moon, sugeriría que incluso pudieras centralizar la lógica en la clase App
para una administración más sencilla y códigos subyacentes más limpios.
Agregue la siguiente línea al método App.OnLaunched
:
SystemNavigationManager.GetForCurrentView().BackRequested += App_BackRequested;
E implemente el controlador de esta manera:
private void App_BackRequested(object sender, BackRequestedEventArgs e)
{
var frame = ( Frame )Window.Current.Content;
if ( frame.CanGoBack )
{
frame.GoBack();
e.Handled = true;
}
}
Tomamos el marco de la ventana actual y verificamos si podemos navegar hacia atrás. En caso de que sea posible, manejamos el evento y navegamos. La ventaja de esto es que ahora puede eliminar todas las acciones relacionadas con BackRequested
en todas las páginas.
También puede hacer algo similar para AppViewBackButtonVisibility
: agregue lo siguiente al final de OnLaunched
:
rootFrame.Navigated += RootFrame_Navigated;
Y ahora implementa el controlador como:
private void RootFrame_Navigated(object sender, NavigationEventArgs e)
{
var frame = (Frame)Window.Current.Content;
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
frame.CanGoBack ? AppViewBackButtonVisibility.Visible :
AppViewBackButtonVisibility.Collapsed;
}
Cada vez que el marco navega, la visibilidad del botón Atrás se actualizará automáticamente.