Shell Navigation in .NET MAUI to a page with tabs

1k views Asked by At

I have a .NET MAUI application. On the main page I have a list of items and when I select one of them, I want to navigate to a different view that has tabs (Summary and Details) related to the selected item. I was wondering how to achieve this.

I was first thinking of registering the route to the tabbed page using Routing.RegisterRoute, but then I read the TabbedPage documentation where it says that "TabbedPage is incompatible with .NET MAUI Shell apps, and an exception will be thrown if you attempt to use TabbedPage in a Shell app."

2

There are 2 answers

1
Peter Wessberg On

You can have two or more TabBar:s and switch between them using 3 slashes Shell.Current.GoToAsync("///MainPage"); which will take you to the MainPage in the bar that you have declared in Route. Read about Routes and the Shell at .NET MAUI Shell navigation

If you want to be able to click on a tab and by doing that go to a page in another TabBar we can intercept the event.

If we have 2 TabBar in Shell

<TabBar Route="Main">
    <ShellContent
        Title="Tab 1"
        ContentTemplate="{DataTemplate local:MainPage}"
        IsVisible="True"
        Route="MainPage" />
    <ShellContent
        Title="Tab 2"
        ContentTemplate="{DataTemplate local:MainPage}"
        IsVisible="False"
        Route="MainPage2" />
    <ShellContent
        Title="To the next bar"
        ContentTemplate="{DataTemplate views:TestView}"
        IsVisible="True"
        Route="TestView" />
</TabBar>

<TabBar Route="SecondBar">
    <ShellContent
        Title="Tab in bar"
        ContentTemplate="{DataTemplate local:MainPage}"
        IsVisible="True"
        Route="MainPage" />
    <ShellContent
        Title="Next tab"
        ContentTemplate="{DataTemplate views:TestView}"
        IsVisible="True"
        Route="TestView" />
</TabBar>

If we now want to go to TestView and activate SecondBar we need to override OnNavigating in the Shell

public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
    }

    protected override async void OnNavigating(ShellNavigatingEventArgs args)
    {
        base.OnNavigating(args);

        if (args.Source == ShellNavigationSource.Pop || args.Source == ShellNavigationSource.PopToRoot)
        {
            return;
        }

        if (args.Target.Location.OriginalString.Contains("//Main/TestView"))
        {
            args.Cancel();
            await GoToAsync("//SecondBar/TestView");
        }
    }
}

Note! If you are to use <Tab></Tab> they need to have a route as well and be added to the complete path.

2
H.A.H. On

You cannot use Navigation Pages mixed with Shell. You pick one or the other.

So, if I assume that you want to keep using Shell, and you want to keep your idea for tabs, you have to do two things.

  1. Register global route and navigate to it (Shell.xaml.cs), passing your object data as parameter.

  2. Implement a Tab Control.

First part is easy, the second part is the tricky one. You can always try 3rd party controls (DevExpress, Syncfusion, ETC...)

Or you can try implementing one of your own. I recommend reading this for the start: https://dev.to/davidortinau/making-a-tabbar-or-segmentedcontrol-in-net-maui-54ha

This guy is showing some pretty important concepts, and if you get what he is saying, you will learn to do much more that Tab Control.

To summarize what you will read: Tab Control is nothing more than RadioButton and BindableLayout working together.

And if you see the source of those 3rd party controls (just to get inspiration), the first thing you will notice that they look surprisingly similar to each other.

(You should search TabControl in MAUI, I remember other solutions being posted. ToolmakerSteve showed a link about TabBar using Grid as Panels.)