Motivação

Em Aplicações Universais do Windows, quando pressionamos o botão Voltar no topo da tela do desktop ou no próprio smartphone, esperamos navegar de volta para a página anterior àquela que estamos visualizando no momento. No entanto, esse comportamento não vem implementado por padrão quando criamos um novo projeto desse tipo. No desktop esse botão é inicialmente invisível, já no smartphone, apesar de haver o botão físico, seu comportamento não é o esperado: ele faz com que a aplicação seja fechada.

Passo 1: Habilitar o botão

A Figura 1 ilustra o comportamento padrão de um projeto recém-criado no Visual Studio. Repare que o botão Voltar não aparece na janela do lado esquerdo.

App sem botão Voltar por padrão
Figura 1. App sem botão Voltar por padrão

Para gerenciar a visibilidade do botão devemos utilizar a classe SystemNavigationManager, que se encontra no namespace Windows.UI.Core. A partir dela teremos acesso à propriedade AppViewBackButtonVisibility, que deverá receber os valores Visible ou Collapsed, com a seguinte sintaxe:


    SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
    

Essa instrução pode ser utilizada em qualquer ponto do aplicativo, no entanto, é importante definir bem quando o botão Voltar estará ou não visível. Para especificar isso, podemos seguir uma lógica básica: o botão só deve aparecer quando houver uma página para a qual o usuário pode voltar. Seguindo essa ideia podemos perceber, por exemplo, que na página inicial ele deve ficar oculto, mas nas demais ele deve aparecer.

Com base nisso, podemos centralizar o controle do botão Voltar na página inicial da aplicação, tornando-o visível sempre que o usuário navegar para outra página, e invisível quando o usuário voltar para a tela principal. A mostra como podemos fazer esse gerenciamento.

Listagem 1. Exibindo e ocultando o botão Voltar

     protected override void OnNavigatedFrom(NavigationEventArgs e)
     {
         SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
     }
    
     protected override void OnNavigatedTo(NavigationEventArgs e)
     {
         SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
     }
    
  • Linhas 1 a 4: exibimos o botão no evento OnNavigatedFrom, que ocorre sempre que o usuário navega da página atual (nesse caso, a página principal) para uma outra;
  • Linhas 6 a 9: ocultamos o botão no evento OnNavigatedTo, que é disparado quando a navegação ocorre de outra página para a que estamos editando, ou seja, quando o usuário retorna para a página inicial.

Caso executemos a aplicação agora e acessarmos uma segunda página, já veremos o botão Voltar no topo da janela, como mostra a Figura 2.

Página com botão Voltar visível
Figura 2. Página com botão Voltar visível

Passo 2: Configurar o funcionamento do botão

Ao realizar as configurações que acabamos de ver, fazemos com o que o botão esteja visível quando for necessário. Porém, ele ainda não tem funcionalidade implementada, de forma que se clicarmos nele, nada acontecerá.

Para configurar o funcionamento propriamente dito, será necessário tratar o evento BackRequested da classe SystemNavigationManager, que é disparado sempre que o usuário tenta “voltar” na navegação, clicando no botão da página, ou usando o botão físico do dispositivo.

Por se tratar de uma configuração global, que deve estar ativa em qualquer página, ela deve ser feita na classe App, que controla o ciclo de vida da aplicação. Nessa classe, dentro do método OnLaunched (no final dele), devemos adicionar a seguinte linha de código, que define um event handler para o evento BackRequested:


    SystemNavigationManager.GetForCurrentView().BackRequested += App_BackRequested;
    

Feito isso, será preciso criar o método App_BackRequested, cujo código pode ser visto na Listagem 2.

Listagem 2. Método para tratar o evento BackRequested

 private void App_BackRequested(object sender, BackRequestedEventArgs e)
 {
     Frame rootFrame = Window.Current.Content as Frame;

     if (rootFrame == null)
         return;

     if (rootFrame.CanGoBack && e.Handled == false)
     {
             e.Handled = true;
             rootFrame.GoBack();
     }
 }
    
  • Linha 3: obtemos o frame que está sendo visualizado atualmente (conteúdo da página ativa);
  • Linhas 5 e 6: caso esse frame seja nulo, saímos do método sem realizar nenhuma ação;
  • Linhas 8 a 12: através da propriedade CanGoBack do frame, verificamos se o usuário pode navegar para a página anterior e se essa navegação não foi tratada anteriormente (propriedade Handled). Em caso positivo, definimos que essa ação foi tratada nesse ponto (linha 10) e direcionamos o usuário para a página anterior (linha 11).

A partir de agora, sempre que ocorrer navegação, o usuário poderá voltar, caso seja permitido. Se esse não for o comportamento desejável de alguma página, poderemos tratar individualmente cada caso e ocultar ou exibir o botão de acordo com alguma lógica específica. Esse seria o caso, por exemplo, de quando o usuário não pode retornar à tela anterior até concluir alguma ação obrigatória, como o preenchimento de um formulário. Nesse tipo de situação, bastaria tratar os eventos OnNavigetedFrom e OnNavigatedTo e implementar o comportamento desejado.