Con la llegada de las aplicaciones universales en Windows 10 nos hemos encontrado con el problema de manejar la navegación hacia atrás en nuestras apps. En los teléfonos disponemos de un botón físico para ello, pero en los ordenadores o las tablets no disponemos de él, por ello debemos de encontrar una solución limpia a este problema.

Una de las opciones es añadir un botón atrás en cada una de nuestras vistas y mostrarlo u ocultarlo según el tipo de dispositivo en el que la app se esté ejecutando, lo cuál nos dejaría un código parecido a este:

if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
    BackButton.Visibility = Visibility.Collapsed;
    Windows.Phone.UI.Input.HardwareButtons.BackPressed += OnBackButtonPressed;
}

En mi opinión este código es demasiado feo y nos hace incluir demasiadas cosas en cada una de nuestras pantallas, lo cual no es cómodo para una funcionalidad que van a incluir el 99% de nuestras apps.

La opción que más me gusta a mi es la que hace uso de la clase SystemNavigationManager que nos provee Windows, con ella le podemos indicar que nos muestre o no un botón atrás en nuestra pantalla siempre que sea necesario, esto quiere decir que si la app se está ejecutando en un teléfono el botón atrás no será mostrado pero que si en cambio se ejecuta en una tablet o un pc sí que aparecerá.

La forma de mostrar el botón variará según sea un pc o una tablet. En el primer caso se mostrará en la barra superior de la aplicación:

En el caso del modo tablet podremos utilizar el botón inferior:

Para mostraros como implementar esto voy a partir del ejemplo que realicé de aplicación universal con Caliburn.Micro y lo haré de la manera más genérica posible para que nos sirva para todas nuestras aplicaciones.

Lo primero que vamos a hacer es crear una nueva clase ViewModelBase, dicha clase hereda de Screen y será un view model del cuál extenderán el resto de view models de nuestra aplicación, esto nos permitirá incluir en él todo el código que haya que repetir en cada una de nuestras pantallas (la navegación hacia atrás es un buen ejemplo de ello).

Nuestro view model base va a recibir como parámetro en el constructor una instancia de INavigationService para que así tengamos acceso a la navegación. Además de eso vamos a sobrescribir el método OnActivate para añadirle la lógica necesaria para mostrar u ocultar el botón atrás.

protected override void OnActivate()
{
    base.OnActivate();
    SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
        NavigationService.CanGoBack ? AppViewBackButtonVisibility.Visible :
        AppViewBackButtonVisibility.Collapsed;
}

Como puedes ver en el fragmento de código, hemos utilizado el método CanGoBack para decidir si mostrar o no el botón atrás en nuestra pantalla. A partir de ese momento será el sistema operativo quien decida si mostrarlo o no, dependiendo del tipo de dispositivo sobre el que se esté ejecutando la aplicación.

Por último tendremos que extender todos nuestros view models de esta clase en lugar de la clase Screen y así tendremos completado nuestra gestión del botón atrás.

Como has podido ver, de esta manera nos queda un código muy limpio y totalmente extensible. Si añadimos nuevas pantallas a nuestra aplicación no será necesario copiar y pegar un fragmento de código (síntoma de que estamos haciendo algo mal) si no simplemente hacerlas heredar de nuestro view model base.

Como siempre, puedes encontrar todo el código del ejemplo en mi GitHub desde donde lo puedes descargar, probar y modificar sin ningún problema.