Training
Module
Create multi-page .NET MAUI apps with tab and flyout navigation - Training
Use .NET MAUI shell to create multi-page applications with tabs and flyout navigation.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
The .NET Multi-platform App UI (.NET MAUI) NavigationPage provides a hierarchical navigation experience where you're able to navigate through pages, forwards and backwards, as desired. NavigationPage provides navigation as a last-in, first-out (LIFO) stack of Page objects.
NavigationPage defines the following properties:
BarBackground
, of type Brush, specifies the background of the navigation bar as a Brush.BarBackgroundColor
, of type Color, specifies the background color of the navigation bar.BackButtonTitle
, of type string
, represents the text to use for the back button. This is an attached property.BarTextColor
, of type Color, specifies the color of the text on the navigation bar.CurrentPage
, of type Page, represents the page that's on top of the navigation stack. This is a read-only property.HasNavigationBar
, of type bool
, represents whether a navigation bar is present on the NavigationPage. The default value of this property is true
. This is an attached property.HasBackButton
, of type bool
, represents whether the navigation bar includes a back button. The default value of this property is true
. This is an attached property.IconColor
, of type Color, defines the background color of the icon in the navigation bar. This is an attached property.RootPage
, of type Page, represents the root page of the navigation stack. This is a read-only property.TitleIconImageSource
, of type ImageSource, defines the icon that represents the title on the navigation bar. This is an attached property.TitleView
, of type View, defines the view that can be displayed in the navigation bar. This is an attached property.These properties are backed by BindableProperty objects, which means that they can be targets of data bindings, and styled.
The NavigationPage class also defines three events:
Pushed
is raised when a page is pushed onto the navigation stack.Popped
is raised when when a page is popped from the navigation stack.PoppedToRoot
is raised when the last non-root page is popped from the navigation stack.All three events receive NavigationEventArgs
objects that define a read-only Page property, which retrieves the page that was popped from the navigation stack, or the newly visible page on the stack.
Warning
NavigationPage is incompatible with .NET MAUI Shell apps, and an exception will be thrown if you attempt to use NavigationPage in a Shell app. For more information about Shell apps, see Shell.
.NET MAUI supports modeless page navigation. A modeless page stays on screen and remains available until you navigate to another page.
A NavigationPage is typically used to navigate through a stack of ContentPage objects. When one page navigates to another, the new page is pushed on the stack and becomes the active page:
When the second page returns back to the first page, a page is popped from the stack, and the new topmost page then becomes active:
A NavigationPage consists of a navigation bar, with the active page being displayed below the navigation bar. The following diagram shows the main components of the navigation bar:
An optional icon can be displayed between the back button and the title.
Navigation methods are exposed by the Navigation
property on any Page derived types. These methods provide the ability to push pages onto the navigation stack, to pop pages from the stack, and to manipulate the stack.
Tip
It's recommended that a NavigationPage should only be populated with ContentPage objects.
An app that is structured around multiple pages always has a root page, which is the first page added to the navigation stack. This is accomplished by creating a NavigationPage object whose constructor argument is the root page of the app, and setting the resulting object as the value of the App.MainPage
property:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
}
An app that is structured around multiple pages always has a root page, which is the first page added to the navigation stack. This is accomplished by creating a NavigationPage object whose constructor argument is the root page of the app, and setting the resulting object as the root page of a Window:
public partial class App : Application
{
public App()
{
InitializeComponent();
}
protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new NavigationPage(new MainPage()));
}
}
Note
The RootPage
property of a NavigationPage provides access to the first page in the navigation stack.
A page can be navigated to by calling the PushAsync
method on the Navigation
property of the current page:
await Navigation.PushAsync(new DetailsPage());
In this example, the DetailsPage
object is pushed onto the navigation stack, where it becomes the active page.
Note
The PushAsync
method has an override that includes a bool
argument that specifies whether to display a page transition during navigation. The PushAsync
method that lacks the bool
argument enables the page transition by default.
The active page can be popped from the navigation stack by pressing the Back button on a device, regardless of whether this is a physical button on the device or an on-screen button.
To programmatically return to the previous page, the PopAsync
method should be called on the Navigation
property of the current page:
await Navigation.PopAsync();
In this example, the current page is removed from the navigation stack, with the new topmost page becoming the active page.
Note
The PopAsync
method has an override that includes a bool
argument that specifies whether to display a page transition during navigation. The PopAsync
method that lacks the bool
argument enables the page transition by default.
In addition, the Navigation
property of each page also exposes a PopToRootAsync
method that pops all but the root page off the navigation stack, therefore making the app's root page the active page.
The Navigation
property of a Page exposes a NavigationStack
property from which the pages in the navigation stack can be obtained. While .NET MAUI maintains access to the navigation stack, the Navigation
property provides the InsertPageBefore
and RemovePage
methods for manipulating the stack by inserting pages or removing them.
The InsertPageBefore
method inserts a specified page in the navigation stack before an existing specified page, as shown in the following diagram:
The RemovePage
method removes the specified page from the navigation stack, as shown in the following diagram:
Together, these methods enable a custom navigation experience, such as replacing a login page with a new page following a successful login.
.NET MAUI supports modal page navigation. A modal page encourages users to complete a self-contained task that cannot be navigated away from until the task is completed or cancelled.
A modal page can be any of the page types supported by .NET MAUI. To display a page modally, the app should push it onto the modal stack, where it will become the active page:
To return to the previous page the app should pop the current page from the modal stack, and the new topmost page becomes the active page:
Modal navigation methods are exposed by the Navigation
property on any Page derived types. These methods provide the ability to push pages onto the modal stack, and pop pages from the modal stack. The Navigation
property also exposes a ModalStack
property from which pages in the modal stack can be obtained. However, there is no concept of performing modal stack manipulation, or popping to the root page in modal navigation. This is because these operations are not universally supported on the underlying platforms.
Note
A NavigationPage object is not required for performing modal page navigation.
A page can be modally navigated to by calling the PushModalAsync
method on the Navigation
property of the current page:
await Navigation.PushModalAsync(new DetailsPage());
In this example, the DetailsPage
object is pushed onto the modal stack, where it becomes the active page.
Note
The PushModalAsync
method has an override that includes a bool
argument that specifies whether to display a page transition during navigation. The PushModalAsync
method that lacks the bool
argument enables the page transition by default.
The active page can be popped from the modal stack by pressing the Back button on a device, regardless of whether this is a physical button on the device or an on-screen button.
To programmatically return to the original page, the PopModalAsync
method should be called on the Navigation
property of the current page:
await Navigation.PopModalAsync();
In this example, the current page is removed from the modal stack, with the new topmost page becoming the active page.
Note
The PopModalAsync
method has an override that includes a bool
argument that specifies whether to display a page transition during navigation. The PopModalAsync
method that lacks the bool
argument enables the page transition by default.
On Android, you can always return to the previous page by pressing the standard Back button on the device. If the modal page requires a self-contained task to be completed before leaving the page, the app must disable the Back button. This can be accomplished by overriding the Page.OnBackButtonPressed
method on the modal page.
Sometimes it's necessary for a page to pass data to another page during navigation. Two standard techniques for accomplishing this are passing data through a page constructor, and by setting the new page's BindingContext
to the data.
The simplest technique for passing data to another page during navigation is through a page constructor argument:
Contact contact = new Contact
{
Name = "Jane Doe",
Age = 30,
Occupation = "Developer",
Country = "USA"
};
...
await Navigation.PushModalAsync(new DetailsPage(contact));
In this example, a Contact
object is passed as a constructor argument to DetailPage
. The Contact
object can then be displayed by DetailsPage
.
An alternative approach for passing data to another page during navigation is by setting the new page's BindingContext
to the data:
Contact contact = new Contact
{
Name = "Jane Doe",
Age = 30,
Occupation = "Developer",
Country = "USA"
};
await Navigation.PushAsync(new DetailsPage
{
BindingContext = contact
});
The advantage of passing navigation data via a page's BindingContext
is that the new page can use data binding to display the data:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.DetailsPage"
Title="Details">
<StackLayout>
<Label Text="{Binding Name}" />
<Label Text="{Binding Occupation}" />
</StackLayout>
</ContentPage>
For more information about data binding, see Data binding.
Any .NET MAUI View can be displayed in the navigation bar of a NavigationPage. This is accomplished by setting the NavigationPage.TitleView
attached property to a View. This attached property can be set on any Page, and when the Page is pushed onto a NavigationPage, the NavigationPage will respect the value of the property.
The following example shows how to set the NavigationPage.TitleView
attached property:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="NavigationPageTitleView.TitleViewPage">
<NavigationPage.TitleView>
<Slider HeightRequest="44"
WidthRequest="300" />
</NavigationPage.TitleView>
...
</ContentPage>
The equivalent C# code is:
Slider titleView = new Slider { HeightRequest = 44, WidthRequest = 300 };
NavigationPage.SetTitleView(this, titleView);
In this example, a Slider is displayed in the navigation bar of the NavigationPage, to control zooming.
Important
Many views won't appear in the navigation bar unless the size of the view is specified with the WidthRequest and HeightRequest properties.
Because the Layout class derives from the View class, the TitleView
attached property can be set to display a layout class that contains multiple views. However, this can result in clipping if the view displayed in the navigation bar is larger than the default size of the navigation bar. However, on Android, the height of the navigation bar can be changed by setting the NavigationPage.BarHeight
bindable property to a double
representing the new height.
Alternatively, an extended navigation bar can be suggested by placing some of the content in the navigation bar, and some in a view at the top of the page content that you color match to the navigation bar. In addition, on iOS the separator line and shadow that's at the bottom of the navigation bar can be removed by setting the NavigationPage.HideNavigationBarSeparator
bindable property to true
.
Tip
The BackButtonTitle
, Title
, TitleIconImageSource
, and TitleView
properties can all define values that occupy space on the navigation bar. While the navigation bar size varies by platform and screen size, setting all of these properties will result in conflicts due to the limited space available. Instead of attempting to use a combination of these properties, you may find that you can better achieve your desired navigation bar design by only setting the TitleView
property.
.NET MAUI feedback
.NET MAUI is an open source project. Select a link to provide feedback:
Training
Module
Create multi-page .NET MAUI apps with tab and flyout navigation - Training
Use .NET MAUI shell to create multi-page applications with tabs and flyout navigation.