Olá pessoal! Tudo bem? Agora que aprendemos como montar uma MasterDetailPage e como montar o menu de navegação de uma MasterDetailPage no Xamarin.Forms, é hora de começar a otimizar o próprio conceito de navegação. Hoje, vamos aprender como usar recursos do C# para facilitar a identificação de qual página deve ser aberta.
Como sempre, fique à vontade para baixar o código fonte deste artigo para estudos.
Este app funciona de forma muito semelhante ao app que criamos quando aprendemos a montar o menu de navegação. Mas para facilitar, vamos criar apenas duas páginas de navegação, o que significa que precisamos de três páginas: Detalhe0, que será exiba quando o app for aberto e as páginas que estarão disponíveis no menu de navegação: Detalhe1 e Detalhe2. As três páginas apresentam apenas um Label
de identificação. Desta forma:
<StackLayout> <Label Text="Escolha a página para no menu" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" /> </StackLayout>
<StackLayout> <Label Text="Esta é a página detalhe 1" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" /> </StackLayout>
A montagem do Menu segue o mesmo esquema que vimos nos artigos anteriores. A página terá uma ListView
. Destaque para a propriedade SeparatorVisibility
com o valor Nome
(para não exibir as linhas de separação entre os itens da lista) e o x:Name
da lista: PrivateListView
.
<StackLayout> <ListView x:Name="PrivateListView" SeparatorVisibility="None"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding Texto}" /> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout>
Note que já configuramos o {Binding}
da lista para a propriedade Texto
. Isso porque a lista será preenchida por objetos do tipo ItemMenu
, que apresenta a propriedade Texto. E é no modelo usado para o preenchimento da lista que criamos a propriedade Type, do tipo Type
, que terá o tipo de página que será aberta se o item correspondente for tocado na lista.
public class ItemMenu { public string Texto { get; set; } public Type Type { get; set; } }
No Code Behind da página Menu, criamos a propriedade PublicListView para permitir acesso à ListView
que declaramos no Xaml. Como já sabemos, é desta forma que a lista é acessada por dentro da MasterDetailPage
. Note também que estamos criando uma lista de ItemMenu
como ItemsSource
da PrivateListView
.
Vale destacar que estamos também preenchendo a propriedade Type
de cada ItemMenu
. Desta forma, cada item está atrelado a uma página.
public partial class Menu : ContentPage { public ListView PublicListView => PrivateListView; public Menu() { InitializeComponent(); PrivateListView.ItemsSource = new List<ItemMenu> { new ItemMenu {Texto = "Ir para detalhe 1", Type = typeof(Detalhe1)}, new ItemMenu {Texto = "ir para detalhe 2", Type = typeof(Detalhe2)} }; } }
Agora vamos montar a classe MasterDetail
, que herda de MasterDetailPage
. No construtor da classe, vamos configurar Master
com o Menu e Detail
como uma NavigationPage que carrega a página Detalhe0.
Por último, da mesma forma como ensinada no último artigo, usando o conceito de cast do C# para conseguir atrelar o método ListViewOnItemSelected
ao evento ItemSelected
da propriedade PublicListView.
public MasterDetail() { Master = new Menu(); Detail = new NavigationPage(new Detalhe0()); ((Menu)Master).PublicListView.ItemSelected += ListViewOnItemSelected; }
O método ListViewOnItemSelected
, que também está na classe MasterDetail é quem faz a navegação de fato. Em primeiro lugar, tentando converter a propriedade SelectedItem
dentro do parâmetro do tipo SelectedItemChangedEventArgs
. Se ele não for um ItemMenu (lembre-se, nós preenchemos a lista com objetos do tipo ItemMenu), o método não faz nada.
Se a conversão for realizada, usamos o método Activator.CreateInstance para criar uma instância da página cujo tipo está guardado na propriedade Type
do ItemMenu que foi visualmente tocado pelo usuário. Usando esta abordagem, a escolha da janela que será navegada se resume a uma linha. Ao final, configuramos IsPresented
como false
para esconder o menu (esconder a página Master
, na verdade) e removemos a seleção da lista que está na página Menu.
private void ListViewOnItemSelected(object sender, SelectedItemChangedEventArgs e) { if (!(e.SelectedItem is ItemMenu item)) return; Detail = new NavigationPage((Page)Activator.CreateInstance(item.Type)); IsPresented = false; ((Menu) Master).PublicListView.SelectedItem = null; }
Veja o resultado:


Mostrando quão interessante é o Xamarin, o ato de guardar o tipo de um objeto e depois instanciá-lo com a classe Activator
é nativo do C#, mas conseguimos usar em outros sistemas operacionais, simplificando ainda nossos apps – neste caso, fazendo com que a navegação entre páginas dentro de um menu se resuma a poucas linhas. Até a próxima!
[]’s
Paulo Roberto