.NET MAUI - Navegação hierárquica com NavigationPage


  Hoje vamos abordar a navegação hierárquica em aplicações .NET MAUI usando o NavigationPage.

As aplicações .NET MAUI fornecem uma experiência de navegação hierárquica usando a classe NavigationPage onde você pode navegar pelas páginas, para frente e para trás.

A classe NavigationPage fornece a navegação como uma pilha (LIFO- last in, first out - último a entrar, primeiro a sair) de objetos Page que permite ao usuário se mover para baixo em uma pilha de páginas e depois subir novamente pelos níveis.

Além de diversas propriedades esta classe define três eventos:

  1. Pushed  - Disparado quando uma página é enviada para a pilha de navegação;

  2. Popped  - Disparado quando uma página é retirada da pilha de navegação;

  3. PoppedToRoot  - Disparado quando a última página não raiz é removida da pilha de navegação;

Todos os três eventos recebem objetos NavigationEventArgs que definem uma propriedade Page somente leitura, que recupera a página que foi exibida da pilha de navegação ou a página recém-visível na pilha.

Obs: Lembrando que NavigationPage é incompatível com aplicações .NET MAUI Shell que usam a navegação baseada em URI.

Realizando a navegação não modal

O .NET MAUI oferece suporte à navegação de página não modal. Uma página não modal fica na tela e permanece disponível até que você navegue para outra página.

Um NavigationPage normalmente é usado para navegar por uma pilha de objetos ContentPage. Quando uma página navega para outra, a nova página é colocada na pilha e se torna a página ativa:

Quando a segunda página retorna para a primeira página, uma página é removida da pilha e a nova página superior fica ativa:

Um NavigationPage consiste em uma barra de navegação, com a página ativa sendo exibida abaixo da barra de navegação contendo um botão de retorno e o título da página :

Podemos definir um ícone opcional entre de retorno e o título.

Os métodos de navegação são expostos pela propriedade Navigation em qualquer tipo que seja derivado de Page e são os seguintes:

Os métodos PushAsync() e PopAsync() possuem uma sobrecarga que inclui um argumento bool que especifica se uma transição de página deve ser exibida durante a navegação.

A seguir veremos um exemplo prático mostrando o uso da navegação hierárquica sem modal.

Exemplo de Fluxo de navegação

Vamos supor um cenário onde temos três páginas: PaginaInicial.xaml, Pagina2. xaml e PaginaFinal.xaml

A seguir veremos o fluxo da navegação hierárquica usado para navegar entre as páginas:

1 - A primeira página adicionada a uma pilha de navegação é referida como a página raiz do aplicativo :

public partial class App : Application
{
  
public App()
   {
     InitializeComponent();
     MainPage =
new NavigationPage(new PaginaInicial());
   }
}

Isso faz com que a instância ContentPage de PaginaInicial seja empurrada para a pilha  de navegação, onde ela se torna a página ativa e a página raiz da aplicação.

2 - Para navegar para Pagina2, é necessário invocar o método PushAsync na propriedade Navigation da página atual :

private async void btnPaginaInicial_Clicked(object sender, EventArgs e)
{
  
await Navigation.PushAsync(new Pagina2());
}

Isso faz com que a instância de Pagina2 seja empurrada para a pilha de navegação, onde ela se torna a página ativa

A página ativa pode ser extraída da pilha de navegação pressionando o botão Voltar  no dispositivo, independentemente de se tratar de um botão físico no dispositivo ou  de um botão na tela.

Para retornar via código à página original, a instância Pagina2 deve  invocar o método PopAsync:

private void button2_Clicked(object sender, EventArgs e)
{
   Navigation.PopAsync();
}
 

Assim como os métodos PushAsync e PopAsync, a propriedade de navegação de cada página também fornece um método PopToRootAsync :

Esse método remove todas, exceto a página raiz da pilha de navegação, tornando a página raiz do aplicativo a página ativa:

private void button2_Clicked(object sender, EventArgs e)
{
   Navigation.PopToRootAsync();
}

Observe que os métodos para navegação são expostos pela proriedade Navigation.

Recursos usados:

Criando o projeto

No VS 2022 Community vamos criar um projeto usando o template .NET MAUI App e nomeá-lo como MauiNavigation :

Vamos criar no projeto a pasta Pages e nesta pasta vamos criar três ContentPage :

  1. PaginaInicial.xaml

  2. Pagina2.xaml

  3. PaginaFinal.xaml

A seguir temos o código XAML e o código de cada arquivo code-behind:

1- PaginaInicial.xaml

<?xml version="1.0" encoding="utf-8" ?>
<
ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            
x:Class="MauiNavigation.Pages.PaginaInicial"
            
Title="Página Inicial">

   <VerticalStackLayout VerticalOptions="Center" Padding="30">
 
       <
Button Text="Ir para a Página 2"
              
FontSize="20"
              
x:Name="btnPaginaInicial"
              
Clicked="btnPaginaInicial_Clicked"/>

   </
VerticalStackLayout>

</ContentPage>

1- PaginaInicial.xaml.cs

public partial class PaginaInicial : ContentPage
{
  
public PaginaInicial()
   {
      InitializeComponent();
   }

  
private async void btnPaginaInicial_Clicked(object sender, EventArgs e)
   {
     
await Navigation.PushAsync(new Pagina2());
   }
}

2- Pagina2.xaml

<?xml version="1.0" encoding="utf-8" ?>
<
ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            
x:Class="MauiNavigation.Pages.Pagina2"
             BackgroundColor="Aquamarine"
            
Title="Página 2">

     <VerticalStackLayout VerticalOptions="Center" Padding="30" Spacing="30">

       <
Button Text="Ir para a Página Final"
              
FontSize="20"
              
x:Name="button1"
              
Background="Black"
              
Clicked="button1_Clicked"/>

       <
Button Text="Ir para a Página Inicial"
              
x:Name="button2"
              
FontSize="20"
              
Background="Red"
              
Clicked="button2_Clicked"/>

      </
VerticalStackLayout>

</ContentPage>

2- Pagina2.xaml.cs

public partial class Pagina2 : ContentPage
{
  
public Pagina2()
   {
      InitializeComponent();
   }

  
private void button1_Clicked(object sender, EventArgs e)
   {
      Navigation.PushAsync(
new PaginaFinal());
   }

  
private void button2_Clicked(object sender, EventArgs e)
   {
      Navigation.PopAsync();
   }
}

3- PaginaFinal.xaml

<?xml version="1.0" encoding="utf-8" ?>
<
ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            
x:Class="MauiNavigation.Pages.PaginaFinal"
            
Title="Página Final">

     <VerticalStackLayout VerticalOptions="Center" Padding="30" Spacing="30" >

         <
Button Text="Ir para a Página 2"
                
FontSize="20"
                
x:Name="button1"
                
BackgroundColor="Black"
                
Clicked="button1_Clicked" />

         <
Button Text="Ir para a Página Inicial"
                
FontSize="20"
                
x:Name="button2"
                
Clicked="button2_Clicked" />

       </VerticalStackLayout>

</ContentPage>

3- PaginaFinal.xaml.cs

public partial class PaginaFinal : ContentPage
{
  
public PaginaFinal()
   {
       InitializeComponent();
   }

   private void button1_Clicked(object sender, EventArgs e)
   {
     Navigation.PopAsync();
   }

  
private void button2_Clicked(object sender, EventArgs e)
   {
     Navigation.PopToRootAsync();
   }
}

No arquivo App.xaml.cs vamos definir a página inicial como sendo a página PaginaInicial.xaml:

public partial class App : Application
{
  
public App()
   {
     InitializeComponent();
     MainPage =
new NavigationPage(new PaginaInicial());
   }
}

Executando o projeto teremos o resultado abaixo:

Em outro artigo veremos a navegação modal.

Pegue o código do projeto aqui:  MauiNavigation.zip

"Não vos esqueçais da hospitalidade, porque por ela alguns, não o sabendo, hospedaram anjos."
Hebreus 13:2

Referências:


José Carlos Macoratti