Xamarin: Master/Details exampleNel seguito propongo un esempio pratico e semplicissimo di utilizzo di una pagina Master Detail, con tanto di menù di navigazione della nostra App. Il tutto ovviamente usando solo ed esclusivamente Xamarin.Forms (... e il che non è poco..).

La classe MasterDetailPage permette di costruire pagine costituite da due "panelli": uno superiore, il Master, e uno inferiore, chiamato Details.

Oss.: vedere la figura proposta: il menù è la pagina Master, altra è la Deatails. Più facile a vedersi che a spiegarsi.

Proprio per tale motivo tale classe propone, tra le altre, due proprietà: Master e Details (ma guardà un pò....).

Queste devono essere inzializzate a due pagine differenti. In fase di RunTime è possibile modificare queste proprietà: cliccare sulla voce di menù e cambiare il dettaglio. Come al solito un esempio fornirà subito chiarezza.

Nel nostro esempio il pannello superiore Master conterrà un menù, con alcune voci, cliccando le quali nel pannelo details verranno aperte le pagine relative. Partiamo dalle pagine che saranno visualizzate nel dettaglio.

 

public class PaginaDettaglio01 : ContentPage
{
		public PaginaDettaglio01 (){
			Content = new Label{ Text = "PaginaDettaglio01" };
		}
}

public class PagineDettaglio02 : ContentPage
{
		public PagineDettaglio02 (){
			Content = new Label{ Text = "PaginaDettaglio02" };
		}
}

public class PagineDettaglio03 : ContentPage
{
			public PagineDettaglio03 (){
				Content = new Label{ Text = "PaginaDettaglio02" };
		}
}

Nulla di emozionante dire: ma daltronde l'esempio verte su altro.... Ora creiamo la pagina che verrà utilizzata per il menù che porremo nella parte Details.

 

public class MenuPage : ContentPage
	{
		public ListView Menu { get; set; }

		public MenuPage ()
		{
			Title = "Menu Fantatico";
			Menu = new MenuListView ();

			var menuLabel = new ContentView {
				Padding = new Thickness (10, 36, 0, 5),
				Content = new Label {
					Text = "MENU", 
				}
			};

			var layout = new StackLayout { 
				Spacing = 0, 
				VerticalOptions = LayoutOptions.FillAndExpand
			};
			layout.Children.Add (menuLabel);
			layout.Children.Add (Menu);

			Content = layout;

		}
	}

	public class MenuListView : ListView
	{
		public MenuListView ()
		{
			List data = new MenuListData ();

			ItemsSource = data;
			VerticalOptions = LayoutOptions.FillAndExpand;
			BackgroundColor = Color.Transparent;

			var cell = new DataTemplate (typeof(ImageCell));
			cell.SetBinding (TextCell.TextProperty, "VoceMenu");

			ItemTemplate = cell;
		}
	}

	public class MenuItem
	{
		public string VoceMenu { get; set; }

		public Type TipoTargetVoceMenu { get; set; }
	}

	public class MenuListData : List
	{
		public MenuListData ()
		{
			this.Add (new MenuItem () { 
				VoceMenu = "Pagina con Dettaglio 01", 
				TipoTargetVoceMenu = typeof(PaginaDettaglio01)
			});

			this.Add (new MenuItem () { 
				VoceMenu = "Pagina con Dettaglio 02", 
				TipoTargetVoceMenu = typeof(PagineDettaglio02)
			});

			this.Add (new MenuItem () { 
				VoceMenu = "Pagina con Dettaglio 03", 
				TipoTargetVoceMenu = typeof(PagineDettaglio03)
			});
		}
	}

Nella pratica con il codice sopra creiamo una classe che tiene le info relative a ogni voce di menù: la classe MenuItem. In questa salviamo la voce di menù stessa che andremo a visualizzare, nonchè il tipo di pagina associata alla voce di menù. Ricordiamo che Type è semplicemente un tipo che permette di memorizzare il tipo di un dato.

public App ()
{

  var menuPage = new MenuPage ();
  menuPage.Menu.ItemSelected += (sender, e) => CambioDetails (e.SelectedItem as MenuItem);
  MainPage = new MasterDetailPage {
    Master=menuPage,
    Detail=new NavigationPage(new PaginaDettaglio01()),
					IsPresented=true
  };

}

void CambioDetails (MenuItem menu)
{
  Page displayPage = (Page)Activator.CreateInstance (menu.TipoTargetVoceMenu);
  ((MasterDetailPage)this.MainPage).Detail = new NavigationPage (displayPage);
  ((MasterDetailPage)this.MainPage).IsPresented =  false;
}

Qui abbiamo "unito tutti i puntini": il nostro codice crea una pagine MasterDetails e pone come Master la pagina Menù, e come Details per iniziare la pagina 01. Siccome la pagine menù espone la listview allora qui è possibile intercettarne l'evento ItemSelected, che cambia il Details a seconda di cosa si è selezionato.

L'unica cosa che può dare "disturbo" è Activator in CambioDetails, che semplicemente permette di creare istanze tra le altre possibilità di classe proponendo come argomento il tipo.