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.