Advanced Navigation in .NET MAUI

This guide explores advanced navigation patterns and techniques within .NET MAUI, empowering you to build sophisticated and user-friendly mobile applications.

Understanding Navigation Stacks

.NET MAUI uses a NavigationPage to manage a stack of pages. Pushing a new page onto the stack displays it, while popping a page removes it, returning the user to the previous page. This provides a familiar hierarchical navigation experience.

Pushing and Popping Pages

The most basic form of navigation involves pushing a new page onto the navigation stack or popping the current page off.


// Navigating to a new page
await Navigation.PushAsync(new MyNextPage());

// Navigating back
await Navigation.PopAsync();
        

Pushing Modals

For operations that require user interaction without disrupting the main navigation flow, modal pages are ideal. They are presented on top of the current page.


// Presenting a modal page
await Navigation.PushModalAsync(new MyModalPage());

// Dismissing a modal page
await Navigation.PopModalAsync();
        
Note: Modal pages do not participate in the standard navigation stack. You must explicitly dismiss them.

Navigation with Parameters

Often, you need to pass data between pages. This can be achieved by passing parameters to the constructor of the destination page.

Passing Data

When navigating, create an instance of the target page and pass the required data through its constructor.


// On the source page
var userId = 123;
await Navigation.PushAsync(new UserProfilePage(userId));

// On the destination page (UserProfilePage.xaml.cs)
public partial class UserProfilePage : ContentPage
{
    private int _userId;

    public UserProfilePage(int userId)
    {
        InitializeComponent();
        _userId = userId;
        LoadUserData(_userId);
    }

    private void LoadUserData(int id)
    {
        // Fetch and display user data based on id
    }
}
        

Deep Linking and Navigation

Deep linking allows users to navigate directly to a specific page or content within your application from external sources like web links or push notifications.

Registering Deep Links

You can configure your application to handle specific URI schemes.

In your MauiProgram.cs:


public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
        })
        .ConfigureMauiHandlers(handlers =>
        {
            // Example: Registering a custom handler if needed for specific routing
        });

    // Configure URI scheme for deep linking
    Microsoft.Maui.Hosting.MauiApp.SetGlobalConfigurationValue("UriScheme", "myapp");

    return builder.Build();
}
        

Handling Incoming URIs

Override the OnAppLinkRequestReceived method in your App.xaml.cs.


public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        MainPage = new AppShell(); // Or your initial page
    }

    protected override async void OnAppLinkRequestReceived(Uri uri)
    {
        base.OnAppLinkRequestReceived(uri);

        if (uri.Scheme == "myapp")
        {
            var host = uri.Host;
            var path = uri.AbsolutePath;

            if (host == "userprofile" && path.StartsWith("/"))
            {
                var userIdString = path.Substring(1); // Remove leading slash
                if (int.TryParse(userIdString, out int userId))
                {
                    // Navigate to the user profile page
                    // Note: Ensure your MainPage is a NavigationPage or has a Navigation property
                    if (MainPage is NavigationPage navigationPage)
                    {
                        await navigationPage.PushAsync(new UserProfilePage(userId));
                    }
                    else
                    {
                        // Handle cases where MainPage is not a NavigationPage or is Shell
                        // You might need to access Shell navigation or set a new NavigationPage
                        await Navigation.PushAsync(new UserProfilePage(userId)); // This might need adjustment based on your AppShell setup
                    }
                }
            }
        }
    }
}
        
Important: Ensure that your MainPage is wrapped in a NavigationPage if you intend to use Navigation.PushAsync directly within OnAppLinkRequestReceived. Alternatively, integrate with AppShell navigation.

Shell Navigation

.NET MAUI's Shell provides a streamlined way to build cross-platform applications with a consistent navigation structure. It simplifies common navigation patterns.

Flyout and Tab Navigation

Shell supports flyouts (drawers) and bottom tabs for primary navigation. Define your navigation hierarchy in your AppShell.xaml.


<!-- AppShell.xaml -->
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:YourAppName"
       x:Class="YourAppName.AppShell"
       Shell.FlyoutBehavior="Disabled">

    <ShellContent Title="Home"
                  ContentTemplate="{DataTemplate local:HomePage}"
                  Route="HomePage" />

    <ShellContent Title="About"
                  ContentTemplate="{DataTemplate local:AboutPage}"
                  Route="AboutPage" />

    <ShellContent Title="User Profile"
                  ContentTemplate="{DataTemplate local:UserProfilePage}"
                  Route="userprofile" />

    <!-- Example of adding tabs -->
    <TabBar>
        <ShellContent Title="Tab 1" Icon="tab1_icon.png" ContentTemplate="{DataTemplate local:TabOnePage}" />
        <ShellContent Title="Tab 2" Icon="tab2_icon.png" ContentTemplate="{DataTemplate local:TabTwoPage}" />
    </TabBar>
</Shell>
        

Navigating Within Shell

You can navigate between Shell items using their routes.


// Navigating to a page defined by a route
await Shell.Current.GoToAsync("userprofile?id=456"); // With query parameters

// Navigating back in Shell
await Shell.Current.GoToAsync("..");
        

Navigation with Query Parameters

Pass data as query parameters in Shell navigation for cleaner URIs.


// Navigating with query parameters
await Shell.Current.GoToAsync($"userprofile?id=789");

// On the destination page (UserProfilePage.xaml.cs)
[QueryProperty(nameof(UserId), "id")]
public partial class UserProfilePage : ContentPage
{
    public string UserId { get; set; }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        if (int.TryParse(UserId, out int id))
        {
            LoadUserData(id);
        }
    }

    private void LoadUserData(int id)
    {
        // Fetch and display user data
    }
}
        

Custom Navigation Transitions

Enhance user experience by customizing page transitions.


// Custom transition for PushAsync
await Navigation.PushAsync(new MyCustomTransitionPage(), animate: true); // Default animation

// You can also define custom animations using AnimationExtensions or third-party libraries.
// .NET MAUI currently offers basic animation control. For more advanced, consider custom renderers or platform-specific code.
        

Explore the official .NET MAUI documentation for more in-depth details and advanced scenarios.

Back to Top