MasterDetailPage Navigation Menu in Xamarin Forms

One of the most common forms of navigation in an Xamarin Forms application, is by the MasterDetailPage. This also may be referred to as the Flyout Menu, SlideOut Menu or Navigation Drawer. A hidden panel is kept out to the side of the screen and then via a button tap, or a right swipe, it will appear.

If you want to follow along in the code, have a look at my sample Github repo, NavigationMenu.

Creating MasterDetailPage

While you can create a MasterDetailPage in XAML, it’s normally easier to establish this in code. It is comprised of a Master Page, which is the menu, and a Detail page, which will have your main app pages. In the Detail page, it is normally common to have a NavigationPage as the root control, to allow navigation within the Detail page.

MainPage = new MasterDetailPage()
{
    Master = new MasterPage() { Title = "Main Page" },
    Detail = new NavigationPage(new PageOne())
};

You must set a Title, on your Master page. Note, that MasterPage() and PageOne() are just ContentPage’s I created myself in the project. You can call these whatever you want.

Adding Navigation Items

Now we get to add navigation links to our Master page. There are numerous options here. You can use a ListView, if you desire, however I find it easier to create a new control, and use a StackLayout. These navigation items are static in most apps, and a ListView is designed for dynamically loaded data.

Let’s create a NavigationItem control. You will also notice I use Iconize, with the FontAwesome module, for the icons.

<?xml version="1.0" encoding="UTF-8"?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
      xmlns:iconize="clr-namespace:FormsPlugin.Iconize;assembly=FormsPlugin.Iconize"
      x:Name="this"
      x:Class="NavigationMenu.NavigationItem">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <iconize:IconImage Grid.Column="0" Icon="{Binding Icon, Source={x:Reference this}}" IconColor="Gray" IconSize="22" />
    <Label Text="{Binding Text, Source={x:Reference this}}" Grid.Column="1" />
    <Grid.GestureRecognizers>
        <TapGestureRecognizer Command="{Binding Command, Source={x:Reference this}}" CommandParameter="{Binding CommandParameter, Source={x:Reference this}}" />
    </Grid.GestureRecognizers>
</Grid>

You will notice that this control has bindable properties. We need to create 4 bindable properties. Instead of showing the code in the post, have a look at NavigationItem.xaml.cs on Github.

Setting Our Navigation Items

In our Master page, we now want to add some navigation items. Here is an example of 2 NavigationItems, with a profile image header. For the rounded image, I used Circle Image Control.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:NavigationMenu"
             xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"
             x:Class="NavigationMenu.MasterPage">
    <ContentPage.Content>
        <Grid BackgroundColor="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="200" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid>
                <Image Source="bg.png" Aspect="AspectFill" />
                <StackLayout Padding="0,20,0,0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
                    <controls:CircleImage BorderColor="White" BorderThickness="2" Source="profile.png" Aspect="AspectFill" WidthRequest="85" HeightRequest="85" />
                    <Label Text="Adam Pedley" TextColor="White" FontSize="Large" />
                </StackLayout>
            </Grid>
            <StackLayout Margin="20,20,20,0" Grid.Row="1" Spacing="15">
                <local:NavigationItem Text="Page One" Icon="fa-archive" Command="{Binding NavigationCommand}" CommandParameter="1" />
                <ContentView HeightRequest="1" BackgroundColor="Gray" />
                <local:NavigationItem Text="Page Two" Icon="fa-cog" Command="{Binding NavigationCommand}" CommandParameter="2" />
            </StackLayout>
        </Grid>
    </ContentPage.Content>
</ContentPage>

In your ViewModel, or page, bind the Command to a method that will navigate as desired. You can see here, I used CommandParameter to differentiate each item, so that you only need to create one command, and can then perform a switch based on the value.

Warning: Hiding navigation in a side menu, can cause a drop in user engagement. Ensure the main screen’s in your app, are accessible via the top or bottom toolbar, and the side navigation is used for screen’s that you need to give access to, but are not essential to the user experience.

Microsoft MVP | Xamarin MVP | Xamarin Certified Developer |
Exrin MVVM Framework | Xamarin Forms Developer | Melbourne, Australia

Related Posts

One Comment

  1. Shimmy Weitzhandler

    Was worth coming here even only to learn about the `{x:Reference this}` in your code! I didn’t know that exists and always had to name the parent container!

Leave A Comment?