Xamarin Forms MasterDetail Page Navigation Recipe

In this recipe I will show you how to add a hamburger menu to your Xamarin Forms application using the MasterDetailPage class. The Xamarin.Forms MasterDetail Page consists of one page for the master and one or more pages for the detail.

When used for the main navigation, as in this recipe, we will have a single master page and 4 detail pages. The code for this recipe comes from the Xamarin Forms CRM sample. I have simplified and streamlined the code, and a full Xamarin Studio solution is included at the bottom of this post.

Xamarin.Forms MasterDetail

Think of the MasterDetailPage as the traffic cop of your application navigation. When a user clicks on the hamburger menu, Xamarin.Forms MasterDetail pushes the menu onto the screen. Then when the user taps on a menu item, MasterDetail creates the target page and pushes it onto the stack. Besides those two things, and some styling, MasterDetail doesn’t do much. Have a look at the code.

public class RootPage : MasterDetailPage
{
	public RootPage ()
	{
		var menuPage = new MenuPage ();
		menuPage.Menu.ItemSelected += (sender, e) => 
                             NavigateTo (e.SelectedItem as MenuItem);
		Master = menuPage;
		Detail = new NavigationPage (new ContractsPage ());
	}

	void NavigateTo (MenuItem menu)
	{
		Page displayPage = (Page)Activator.CreateInstance (menu.TargetType);
		Detail = new NavigationPage (displayPage);
		IsPresented = false;
	}
}

Pretty simple right? The only complicated bit is with the (Page)Activator.CreateInstance (menu.TargetType) part, but if you have been doing C# on .Net for a while, you probably have seen it before. All it is, is another way of creating objects.

MasterBehavior

In Xamarin.Forms 1.3, the Xamarin.Forms MasterDetail MasterDetail Page received a new property called MasterBehavior. This property controls how the menu will react when activated. The enumeration MasterBehavior has a few options and they are:

public enum MasterBehavior
{
    Default,
    Popover,
    Split,
    SplitOnLandscape,
    SplitOnPortrait
}

The normal behavior of the MasterDetailPage in landscape mode is “SplitOnLandscape”. I think splitting is normal when using the MasterDetailPage for detail drill in type navigation but not when using it as a hamburger menu or your apps main navigation. When using the MasterDetailPage for app navigation, I set the behavior to popover.

The Menu Page

The menu page is just what the name implies, it’s the Xamarin Forms page that will be shown when the user clicks the menu button. This is the master part of the Xamarin.Forms MasterDetail Page. Our MenuPage is a simple content page with a StackLayout containing a label and a ListView of our menu items.

Please note the public property Menu. This property allows our MasterDetail page access to the ItemSelected event. When the event is fired, the item selected will be sent to the NavigateTo method on the master detail object.

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

	public MenuPage ()
	{
		Icon = "settings.png";
		Title = "menu"; // The Title property must be set.
		BackgroundColor = Color.FromHex ("333333");

		Menu = new MenuListView ();

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

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

		Content = layout;
	}
}

Menu Item

Menu Item is a simple type that holds our menu data and the most important data is the Target type. When a user clicks on a menu item, the NavigateTo method will create a new page from the TargetType, and push that page onto the stack.

public class MenuItem
{
	public string Title { get; set; }
	public string IconSource { get; set; }
	public Type TargetType { get; set; }
}

Menu List View

The menu list view couldn’t be simpler; we use the built in ImageCell for the rows and set the bindings to the properties on the MenuItem type. We set the first item as the selected item and also used it when constructing the MasterDetail Page initial detail class.

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, "Title");
		cell.SetBinding (ImageCell.ImageSourceProperty, "IconSource");

		ItemTemplate = cell;
	}
}

Menu List Data

The MenuListData class is a data structure holding our applications navigation. In your app you could get this data from the database or configuration file. The menu structure of my application doesn’t change much, so I just use code.

public class MenuListData : List
{
	public MenuListData ()
	{
		this.Add (new MenuItem () { 
			Title = "Contracts", 
			IconSource = "contracts.png", 
			TargetType = typeof(ContractsPage)
		});

		this.Add (new MenuItem () { 
			Title = "Leads", 
			IconSource = "Lead.png", 
			TargetType = typeof(LeadsPage)
		});

		this.Add (new MenuItem () { 
			Title = "Accounts", 
			IconSource = "Accounts.png", 
			TargetType = typeof(AccountsPage)
		});

		this.Add (new MenuItem () {
			Title = "Opportunities",
			IconSource = "Opportunity.png",
			TargetType = typeof(OpportunitiesPage)
		});
	}
}

The Content Pages

These pages are what is created when a user clicks on our menu items.

public class ContractsPage : ContentPage
{
	public ContractsPage (){}
}

public class LeadsPage : ContentPage
{
	public LeadsPage (){}
}

public class AccountsPage : ContentPage
{
	public AccountsPage (){}
}

public class OpportunitiesPage : ContentPage
{
	public OpportunitiesPage (){}
}

Download the source code PSC-MasterDetail.zip (79.74 kb)

Happy coding!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.