Implementing MasterDetailPage With TabbedPage In Xamarin.Forms

This is my second article on C# Corner. In this write-up, we are going to see about MasterDetailPage with TabbedPage. Seems unusual but it is certainly not. Many popular apps out there have the same architecture, for example, C# Corner, Paytm, Google’s Play Store App, and many more. Have a look at the following C# Corner app screenshot with the blend of MasterDetailPage & TabbedPage.

Implementing MasterDetailPage With TabbedPage In Xamarin.Forms

MasterDetailPage

According to Microsoft docs, the Xamarin.Forms MasterDetailPage is a page that manages two related pages of information – a master page that presents items, and a detail page that presents details about items on the master page.
 
TabbedPage 
 
According to Microsoft docs, the Xamarin.Forms TabbedPage consists of a list of tabs and a larger detailed area, with each tab loading content into the detail area.

Requirement

  • Microsoft Visual Studio Enterprise 2017(VS Community as well can be used) Along with installing the latest version of Xamarin.
  • Windows 10 & macOS Mojave machine in order to see the output in for both  Android & iOS (Mac is not mandatory).

Implementation

Open Visual Studio 2017 -> Click File -> New -> Create Project -> Select Mobile App (Xamarin.Forms) template & input the preferred name for your project. Check the screenshot below.
 
Implementing MasterDetailPage With TabbedPage In Xamarin.Forms
 
Click Ok. Now, you will see the Cross-platform app screen. Select the options as in the below screenshot & press OK.
 
Implementing MasterDetailPage With TabbedPage In Xamarin.Forms

Above, in the Platform menu, I am including Android and iOS options. If you wish to select all three options, you can do so. It doesn’t take anything extra.

Right-click on the Shared project and add a View folder. Right-click View, go to -> Add -> New Item. The following window will appear.

 Implementing MasterDetailPage With TabbedPage In Xamarin.Forms

In View folder, add the below Content Pages with either the same names or your preferred names.

  • MainMasterDetailPage.xaml
  • HomeTabbedPage.xaml 
  • MoviePage
  • GamePage
  • MovieListPage
  • SettingPage 

After adding the above pages, your project will look like this. 

Implementing MasterDetailPage With TabbedPage In Xamarin.Forms
 
Let’s jump into the code

When you open your MainMasterDetailPage.xaml file, it will look like this.

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  4.              x:Class="MasterDetailDemo.View.MainMasterDetailPage">  
  5.     <ContentPage.Content>  
  6.         <StackLayout>  
  7.             <Label Text="Welcome to Xamarin.Forms!"  
  8.                 VerticalOptions="CenterAndExpand"   
  9.                 HorizontalOptions="CenterAndExpand" />  
  10.         </StackLayout>  
  11.     </ContentPage.Content>  
  12. </ContentPage>  

MainMasterDetailPage is of type ContentPage. We can change this to MasterDetailPage as MasterDetailPage is the first page of our application associated with TabbedPage. So, we would write this code.

MainMasterDetailPage.xaml

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  4.              xmlns:local="clr-namespace:MasterDetailDemo.View"    
  5.              IsPresented="False"       
  6.              x:Class="MasterDetailDemo.View.MainMasterDetailPage">  
  7.   
  8.     <MasterDetailPage.Master>  
  9.         <ContentPage Title="☰" BackgroundColor="Red">  
  10.             <StackLayout BackgroundColor="#B2EC5D">  
  11.                 <StackLayout Margin="25,10,25,0" Padding="0,15,0,15">  
  12.                     <Image  Margin="10" BackgroundColor="Accent" Aspect="AspectFill" Source="Enrich.png"></Image>  
  13.                 </StackLayout>  
  14.                 <ListView x:Name="navigationDrawerList"  
  15.                   RowHeight="60"  
  16.                   SeparatorVisibility="None"  
  17.                   ItemSelected="OnMenuSelected"  
  18.                   BackgroundColor="#A3C1AD">  
  19.                     <ListView.ItemTemplate>  
  20.                         <DataTemplate>  
  21.                             <ViewCell>  
  22.                                 <StackLayout VerticalOptions="FillAndExpand"  
  23.                                  Orientation="Horizontal"  
  24.                                  Padding="20,10,0,10"  
  25.                                  Spacing="20">  
  26.   
  27.                                     <Image Source="{Binding Icon}"  
  28.                                      WidthRequest="30"  
  29.                                      HeightRequest="30"  
  30.                                      VerticalOptions="Center" />  
  31.                                     <Label Text="{Binding Title}"  
  32.                                      FontSize="Medium"  
  33.                                      VerticalOptions="Center"  
  34.                                      TextColor="Black"/>  
  35.                                 </StackLayout>  
  36.                             </ViewCell>  
  37.                         </DataTemplate>  
  38.                     </ListView.ItemTemplate>  
  39.                 </ListView>  
  40.             </StackLayout>  
  41.         </ContentPage>  
  42.     </MasterDetailPage.Master>  
  43.   
  44.     <MasterDetailPage.Detail>  
  45.         <NavigationPage>  
  46.             <x:Arguments>  
  47.                 <local:HomeTabbedPage/>  
  48.             </x:Arguments>  
  49.         </NavigationPage>  
  50.     </MasterDetailPage.Detail>  
  51. </MasterDetailPage>  

Note
In the above code in MasterDetailPage.Master Tag, I am using Title="☰", because in an iOS application, instead of showing the icon, it displays Title. Therefore, to show the hamburger icon, I used this character. You can change this according to your preference. In Android, the Hambuger icon is displayed by default, without any issue.

When you open your MainMasterDetailPage.xaml.cs file, it would look like this.
  1. public partial class MainMasterDetailPage : ContentPage  
  2. {          
  3.     public MainPage()  
  4.     {  
  5.           InitializeComponent();          
  6.     }  
  7. }  

If you see the above MainMasterDetailPage file inheriting with ContentPage, change it into MasterDetailPage as we did for MainMasterDetailPage.xml file. Below is the .cs file of MainMasterDetailPage.xaml.

MainMasterDetailPage.xaml.cs

  1. namespace MasterDetailDemo.View  
  2. {  
  3.     [XamlCompilation(XamlCompilationOptions.Compile)]  
  4.     public partial class MainMasterDetailPage :MasterDetailPage  
  5.     {  
  6.         public MainMasterDetailPage ()  
  7.         {  
  8.             InitializeComponent ();  
  9.             navigationDrawerList.ItemsSource = GetMasterPageLists();  
  10.         }  
  11.   
  12.         private void OnMenuSelected(object sender, SelectedItemChangedEventArgs e)  
  13.         {  
  14.             var item = (MasterPageList)e.SelectedItem;  
  15.   
  16.             if (item.Title == "Setting")  
  17.             {  
  18.                 Detail.Navigation.PushAsync(new SettingPage());  
  19.                 IsPresented = false;  
  20.             }  
  21.             else  
  22.             {  
  23.                 Application.Current.Properties["MenuName"] = item.Title;  
  24.                 Detail = new NavigationPage(new HomeTabbedPage());  
  25.                 IsPresented = false;  
  26.             }  
  27.         }  
  28.         List<MasterPageList> GetMasterPageLists()  
  29.         {  
  30.             return new List<MasterPageList>  
  31.             {  
  32.                 new MasterPageList() { Title = "Games", Icon = "home.png" },  
  33.                 new MasterPageList() { Title = "Movies", Icon = "admin.png" },  
  34.                 new MasterPageList() { Title = "Setting", Icon = "setting.png" }  
  35.             };  
  36.         }  
  37.     }  
  38.   
  39.   //This class used for binding ListView. We can move it to other separate files as well   
  40.    public class MasterPageList  
  41.     {  
  42.         public string Title { getset; }  
  43.         public string Icon { getset; }  
  44.     }  
  45. }  

Simplify the above code,

  • MainMasterDetailPage.xaml file has navigationDrawerList ListView’s which we bind to MasterPageList method. MasterPageList method returns data to bind navigationDrawerList.

  • MainMasterDetailPage.xaml file has the ListView’s item selected event OnMenuSelected which we are implementing in MainMasterDetailPage.xaml.cs class. When we select items from the side menu, this method is called. Based on a clicked menu, we switch to an appropriate Detail Page.

  • Using Application Properties,  we can store which menu we have clicked, so in the next page, we would change tabs accordingly.

Now, open HomeTabbedPage & write this code.

HomeTabbedPage.xaml

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  4.              xmlns:views="clr-namespace:MasterDetailDemo.View"  
  5.              Title = "Home Page"  
  6.              x:Class="MasterDetailDemo.View.HomeTabbedPage">  
  7.     <TabbedPage.Children>  
  8.         <NavigationPage Title="Games" Icon="games">  
  9.             <x:Arguments>  
  10.                 <views:GamePage/>  
  11.             </x:Arguments>  
  12.         </NavigationPage>  
  13.         <NavigationPage Title="Movies" Icon="camera">  
  14.             <x:Arguments>  
  15.                 <views:MoviePage/>  
  16.             </x:Arguments>  
  17.         </NavigationPage>  
  18.     </TabbedPage.Children>  
  19.   
  20. </TabbedPage>  

HomeTabbedPage.xaml.cs

  1. public partial class HomeTabbedPage : TabbedPage  
  2.     {  
  3.         public HomeTabbedPage ()  
  4.         {  
  5.             InitializeComponent ();  
  6.   
  7.             if (Application.Current.Properties.ContainsKey("MenuName"))  
  8.             {  
  9.                 var menuName = Application.Current.Properties["MenuName"].ToString();  
  10.                 if (menuName == "Movies")  
  11.                 {  
  12.                     this.CurrentPage = Children[1];  
  13.                 }  
  14.             }  
  15.         }  
  16.     }  

Simplify above code,

  • HomeTabbedPage.xaml file has TabbedPage.Children tag which contains NavigationPage’s. Each NavigationPage displays one Tab.

  • HomeTabbedPage.xaml has views variable which contain the path View folder in our solution.

  • HomeTabbedPage.xaml & HomeTabbedPage.xaml.cs both files should be inherited with the same class in our case this is TabbedPage.

  • HomeTabbedPage.xaml.cs file checking Application properties which we set in our previous MainMasterDetailPage.xaml.cs file, based on property value Tabs are being switched.
So far, 80% of our code is completed. Now, we will see the process of switching to child pages.
 
GamePage.xaml
  1. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  3.              NavigationPage.HasNavigationBar="False"  
  4.              x:Class="MasterDetailDemo.View.GamePage">  
  5.     <ContentPage.Content>  
  6.         <StackLayout>  
  7.             <Label Text="Welcome to Xamarin.Forms!"  
  8.                 VerticalOptions="CenterAndExpand"   
  9.                 HorizontalOptions="CenterAndExpand" />  
  10.         </StackLayout>  
  11.     </ContentPage.Content>  
  12. </ContentPage>  

GamePage.xaml.cs

  1. public partial class GamePage : ContentPage  
  2.     {  
  3.         public GamePage ()  
  4.         {  
  5.             InitializeComponent ();  
  6.         }  
  7.     }  

MoviePage.xaml

  1. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  3.              NavigationPage.HasNavigationBar="False"  
  4.              x:Class="MasterDetailDemo.View.MoviePage">  
  5.     <ContentPage.Content>  
  6.         <StackLayout>  
  7.             <Button Text="Movies List" BackgroundColor="#D19FE8" TextColor="#008B8B"  Clicked="Button_Clicked"  
  8.                 VerticalOptions="CenterAndExpand"   
  9.                 HorizontalOptions="CenterAndExpand" />  
  10.         </StackLayout>  
  11.     </ContentPage.Content>  
  12. </ContentPage>  

MoviePage.xaml.cs

  1. public partial class MoviePage : ContentPage  
  2.     {  
  3.         public MoviePage ()  
  4.         {  
  5.             InitializeComponent ();  
  6.         }  
  7.   
  8.         private void Button_Clicked(object sender, EventArgs e)  
  9.         {  
  10.             (App.Current.MainPage as MasterDetailPage).Detail.Navigation.PushAsync(new MovieListPage());  
  11.         }  
  12.     }  

Simplifying the above code.

  • MoviePage.xaml.cs file has Button_click event, when we are clicking on it, we push a new page. This is just for demo purposes to show you how to push child pages.

  • We are disabling the navigation for MoviePage.xaml so that it won’t show twice in any page.

MovieListPage.xaml

  1. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  3.              Title="Movie List"  
  4.              x:Class="MasterDetailDemo.View.MovieListPage">  
  5.     <ContentPage.Content>  
  6.         <StackLayout>  
  7.             <Label Text="Movie list page"  
  8.                 VerticalOptions="CenterAndExpand"   
  9.                 HorizontalOptions="CenterAndExpand" />  
  10.         </StackLayout>  
  11.     </ContentPage.Content>  
  12. </ContentPage>  

MovieListPage.xaml.cs

  1. public partial class MovieListPage : ContentPage  
  2.     {  
  3.         public MovieListPage ()  
  4.         {  
  5.             InitializeComponent ();  
  6.         }  
  7.     }  

SettingPage.xaml

  1. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  3.               Title="Setting"  
  4.               x:Class="MasterDetailDemo.View.SettingPage">  
  5.     <ContentPage.Content>  
  6.         <StackLayout>  
  7.             <Label Text="This is setting page"  
  8.                 VerticalOptions="CenterAndExpand"   
  9.                 HorizontalOptions="CenterAndExpand" />  
  10.         </StackLayout>  
  11.     </ContentPage.Content>  
  12. </ContentPage>  

SettingPage.xaml.cs

  1. public partial class SettingPage : ContentPage  
  2.     {  
  3.         public SettingPage ()  
  4.         {  
  5.             InitializeComponent ();  
  6.         }  
  7.     }  

Now we move to our App.xaml.cs file to set the MainPage of the Application.

 App.xaml.cs
  1. public App()  
  2. {  
  3.     InitializeComponent();  
  4.   
  5.     MainPage = new MainMasterDetailPage();  
  6. }  

Note
All XAML and .cs files should be inherited by the same class. In XAML files, we have defined a local variable View that should have the same path of our pages. 

These are the output screens. 

This is how the Homepage looks on iOS & Android.
 
 Implementing MasterDetailPage With TabbedPage In Xamarin.Forms Implementing MasterDetailPage With TabbedPage In Xamarin.Forms

This is the MasterPage (iOS) & Child Movie list page (Android).

Implementing MasterDetailPage With TabbedPage In Xamarin.Forms Implementing MasterDetailPage With TabbedPage In Xamarin.Forms
 
Give it a try guys. If you have any doubts, please comment below. I will respond as soon as possible.

Happy coding!


Similar Articles