• Home
  • Documentation
Show / Hide Table of Contents
  • Introduction
  • Getting Started
    • Download and Setup Prism
    • NuGet Packages
    • Productivity Tools
  • Commands
    • Commanding
    • Composite Commands
  • Dependency Injection
    • Getting Started
    • Registering Types
    • Platform Specific Services
    • Exception Handling
    • ContainerLocator
    • Adding a Custom Container
    • Appendix
  • Event Aggregator
  • ViewModelLocator
  • Modules
  • WPF / Uno
    • Introduction
    • Getting Started
    • Converting From Prism 7.x
    • Converting From Prism 6.x
    • View Composition
    • Region Navigation
      • About Navigation in Prism
      • Basic Region Navigation
      • View/ViewModel Participation
      • Navigating to Existing Views
      • Passing Parameters
      • Confirming Navigation
      • Controlling View Lifetime
      • Navigation Journal
    • Interactivity
      • Event To Command
    • Dialog Service
    • Advanced
      • Region Adapters
    • Legacy (Prism 6)
      • Introduction
      • Initializing
      • Managing-Dependencies
      • Modules
      • Implementing-MVVM
      • Advanced-MVVM
      • Composing-the-UI
      • Navigation
      • Communication
      • Deploying
      • Appendix-A-Glossary
      • Appendix-B-Patterns
      • Appendix-C-Prism-Library
      • Appendix-D-Extending-Prism
      • Appendix-E-Click-Once
  • .NET MAUI
    • Getting Started
    • Migrating from Prism.Forms
    • PrismAppBuilder
    • Dependency Injection
    • AppModel
      • IPageLifecycleAware
    • Behaviors
      • Introduction
      • BehaviorBase<T>
      • EventToCommandBehavior
      • PageBehaviorFactory
    • Dialogs
      • Getting Started
      • IPageDialogService
      • IDialogService
    • Navigation
      • Introduction
      • Page Navigation
      • NavigationBuilder
      • Understanding the INavigationResult
      • NavigationExceptions
      • Global Navigation Observer
      • XAML Navigation
    • Regions
      • Introduction
  • Xamarin.Forms
    • Create Your First App
    • Behaviors
      • Working with Behaviors
      • EventToCommand Behavior
      • PageBehaviorFactory
    • Dialogs
      • Dialogs
      • Page Dialog Service
      • Dialog Service
      • Styling Dialogs
    • Navigation
      • Navigation Basics
      • Passing Parameters
      • Confirming Navigation
      • Deep Linking
      • Working w/ MasterDetailPages
      • Working w/ NavigationPages
      • Working w/ TabbedPages
      • XAML Navigation
    • Application Lifecycle
    • Page Lifecycle
    • Additional Platforms
      • GTK

Working with Master-Detail-Pages

The MasterDetailPage is a very special type of page in Xamarin.Forms and it is important to understand first how the MasterDetailPage in Xamarin.Forms itself works before we can hope to understand how it works in Prism.

Fundamentals

The MasterDetailPage is a special type of Multi-Page, which is comprised of two children:

  • The Master Page
  • The Detail Page

The Master Page

The content of the Master is what is used for the Flyout Menu when it is presented. Note that the BindingContext of the Master should be automatically inherited from it's parent the MasterDetailPage.

The Detail Page

The Detail Page will have the content that is generally visible most of the time. This may be to the right of the Master when the Master is presented, or may take up the full screen when the Master is not presented.

Master Detail Structure

In Xamarin.Forms you may see a MasterDetailPage classically constructed like the following sample. Here we have a MasterPage and a ContactsPage. The ContactsPage will be the default page displayed when the MasterDetailPage is navigated to.

<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
                  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                  xmlns:local="clr-namespace:MasterDetailPageNavigation;assembly=MasterDetailPageNavigation"
                  x:Class="MasterDetailPageNavigation.MainPage">
  <MasterDetailPage.Master>
    <local:MasterPage />
  </MasterDetailPage.Master>
  <MasterDetailPage.Detail>
    <NavigationPage>
      <x:Arguments>
        <local:ContactsPage />
      </x:Arguments>
    </NavigationPage>
  </MasterDetailPage.Detail>
</MasterDetailPage>
Note

Xamarin.Forms has a requirement that your Master page MUST contain a Title. It is also important to note that while SOME platforms will automatically provide the classic hamburger menu icon, others such as iOS do not. For those platforms you will need to provide an IconImageSource for the Master page.

Building your MasterDetailPage with Prism

In Prism.Forms however we construct our MasterDetailPage's a little differently. We recommend that you do NOT create a separate MasterPage as this ultimately leads to confusion for many developers. Instead we recommend simply nesting a ContentPage in the MasterDetailPage.Master and building your UI for it there. There will be NO reference to the Detail in the code behind or in XAML.

<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
                  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                  xmlns:local="clr-namespace:MasterDetailPageNavigation;assembly=MasterDetailPageNavigation"
                  x:Class="MasterDetailPageNavigation.MainPage">
  <MasterDetailPage.Master>
    <ContentPage Title="Menu"
            Padding="0,40,0,0"
            IconImageSource="{OnPlatform iOS='hamburger.png'}">
      <StackLayout>
        <Button Text="View A"
                Command="{Binding NavigateCommand}"
                CommandParameter="ViewA" />
      </StackLayout>
    </ContentPage>
  </MasterDetailPage.Master>
</MasterDetailPage>

By adding the MasterContent in this way it remains clear to developers that the ViewModel for that Master is in fact the MainPageViewModel (The ViewModel for our MasterDetailPage itself). When we have our binding for the NavigateCommand this will look for the NavigateCommand in the MainPageViewModel.

Register for Navigation

While there isn't anything particularly special about how we register the impacted Pages, it is important to Remember that we are in fact dealing with three pages here and not one. When we register our MasterDetailPage we need to remember that we want the top title bar and as a result we will need to ensure that we have a registered NavigationPage. This can be literally any NavigationPage, either one you have customized or the NavigationPage straight from Xamarin.Forms:

public class App : PrismApplication
{
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterForNavigation<NavigationPage>();
        containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>();
        containerRegistry.RegisterForNavigation<ViewA, ViewAViewModel>();
    }
}

Navigating to the MasterDetailPage

Note

A MasterDetailPage is considered a ROOT page. While you can technically have more than one used in your app, the MasterDetailPage should be navigated to with an absolute uri to reset the NavigationStack setting the Application.MainPage equal to your MasterDetailPage.

public class App : PrismApplication
{
    protected override void OnInitialized()
    {
        InitializeComponent();
        NavigationService.NavigateAsync("/MainPage/NavigationPage/ViewA");
    }
}

Navigating from the Master page

Earlier we looked at how we could add a simple master right in the XAML of our MasterDetailPage. We bound our button to a Command in our ViewModel named NavigateCommand. Our button simply passed back that we wanted to Navigate to ViewA, however as you remember we want the Navigation bar with the page title, so we need the actual Detail to be the NavigationPage with it's root page being ViewA. We can do this easily by prefing the NavigationPage/ before the path we are passed in our Command handler as shown here.

public class MainPageViewModel : BindableBase
{
    public DelegateCommand<string> NavigateCommand { get; }

    private async void NavigateCommandExecuted(string path)
    {
        var result = await _navigationService.NavigateAsync($"NavigationPage/{path}");
    }
}

Additional Resources

  • Sample App
  • Edit on GitHub
  • Ask questions
  • Follow @PrismLib
  • Follow @BrianLagunas
  • Follow @DanJSiegel
Back to top Copyright 2015-2022 Prism