Xamarin.Forms Shell Navigation Hierarchy with parameters

1.3k Views Asked by At

How to define the following navigation hierarchy in a Xamarin.Forms Shell application?

  • Navigation Tab (route "main")
    • Page with Orders List (route "orders")
      • Detail Page for one order (route "order", parameter "orderId")
        • Sub-Detail Page 1 for that particular order (route "details1", parameter "orderId")
        • Sub-Detail Page 2 for that particular order (route "details2", parameter "orderId")

It works well as long as there is only the order page without having the sub-detail pages defined. I can navigate then to that page via Shell.Current.GoToAsync("//main/orders/order?orderId=5") route.

But when I add the sub-detail pages (doesn't matter if I do this via XAML or Routing.RegisterRoute), the same GoToAsync call fails with System.ArgumentException: 'unable to figure out route for: //main/orders/order?orderId=5'

Hierarchy definition via XAML:

<Tab Title="My Orders" Route="main">
    <ShellContent ContentTemplate="{DataTemplate pages:OrdersListPage}" Route="orders">
        <ShellContent ContentTemplate="{DataTemplate pages:OrderPage}" Route="order">
            <ShellContent ContentTemplate="{DataTemplate pages:OrderDetailPage1}" Route="details1" />
            <ShellContent ContentTemplate="{DataTemplate pages:OrderDetailPage2}" Route="details2" />
        </ShellContent>
    </ShellContent>
</Tab>

Same exception when I define it via custom routes:

Routing.RegisterRoute("main/orders/order", typeof(pages:OrderPage));
Routing.RegisterRoute("main/orders/order/details1", typeof(pages:OrderDetailPage1));
Routing.RegisterRoute("main/orders/order/details1", typeof(pages:OrderDetailPage1));
1

There are 1 best solutions below

1
On BEST ANSWER

I have a workaround for this, you could RegisterRoute for the third and fourth level Route again in the AppShell.xaml.cs.

As follows:

Routing.RegisterRoute("Order", typeof(OrderPage));
Routing.RegisterRoute("Details1", typeof(OrderDetailPage1));

Then can use the follow route path to navigate:

Shell.Current.GoToAsync("//main/orders/Order/Details1?orderId=5")

If you Register the Route for each Page in .cs code, it will work. Generally, the first and second level if defined in Xaml, it seems not need to re-register in code again. Therefore, I only re-register the third and fourth Route with a name-key, not a path-key.