Xamarin.Forms Shell Navigation Hierarchy with parameters - xamarin.forms

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));

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.

Related

How to disable a ShellContent button

I have a brand new Xamarin Shell application. I just want to disable one of the buttons in the TabBar section. I see there is an IsEnabled property but even if I set it to False, the button is still clickable and the view becomes visible.
<TabBar>
<ShellContent Title="Home" Route="HomePage" ContentTemplate="{DataTemplate local:HomePage}"/>
<ShellContent Title="Settings" Route="SettingsPage" ContentTemplate="{DataTemplate local:SettingsPage}" IsEnabled="False" />
</TabBar>
Is it not possible to disable the buttons that appear in the lower navigation of a Xamarin.Forms application? I was hoping to disable certain buttons when conditions weren't met and enable them using event listeners.
I believe #ToolmakerSteve's comments would work, what I ended up doing was putting each ShellContent in its own Tab:
<TabBar>
<Tab>
<ShellContent Title="Home" Route="HomePage" ConentTemplate="{DataTemplate local:HomePage}"/>
</Tab>
<Tab>
<ShellContent Title="Settings" Route="SettingsPage" ContentTemplate="{Data Template local:SettingsPage}" IsEnabled="False" />
</Tab>
</TabBar>
Then I subscribed to events in the ShellContent class and enabled / disabled the Settings button at will.

How do reload page when click item menu in Xamarin.Form Shell Flyout

I'm using the Xamarin.Form Shell Flyout.
When click item menu, from the second time, the page don't reload.
How do reload page (reload data) when click item menu in Xamarin.Form Shell Flyout?
<FlyoutItem Route="animals" Title="Animals" FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Route="Monkeys" Title="Monkeys" Icon="tab_feed.png" ContentTemplate="{DataTemplate local:MonkeysPage}" />
</FlyoutItem>
You can reload the page in the OnAppearing method:).

Xamarin Forms Shell bind flyout icon theme aware

I have a Xamarin Forms Shell Application with a flyout. My entries are defined like this:
<FlyoutItem Title="{x:Static resources:Strings.DashboardTitle}" FlyoutIcon="ic_dashboard_black">
<Tab>
<ShellContent>
<dashboard:DashboardPage />
</ShellContent>
</Tab>
</FlyoutItem>
This works so far as the icons is shown. But to support light and dark theme I would like for example to be able to bind that with an AppThemeBinding. Is that possible? Or how would I theme the icons in the flyout?
You can use AppThemeBinding markup extension to define image source under light/dark mode:
<FlyoutItem Title="{x:Static resources:Strings.DashboardTitle}" FlyoutIcon="{AppThemeBinding Light=lightlogo.png, Dark=darklogo.png}">
<Tab>
<ShellContent>
</ShellContent>
</Tab>
</FlyoutItem>
The following requirements must be met for Xamarin.Forms to respond to a system theme change:
Xamarin.Forms 4.6.0.967 or greater.
iOS 13 or greater.
Android 10 (API 29) or greater.
UWP build 14393 or greater.
Responding to a system theme change is currently experimental, and can only be used by setting the AppTheme_Experimental flag.
Refer: Enable flags in platform projects

Is there a way to hide the TOP tab bar?

I am using Xamarin.Forms Shell and I have bottom Tab Bar navigation with no Flyout.
<TabBar Route="tabs">
<Tab Title="Page1" Route="page1" Icon="page1.png">
<ShellContent ContentTemplate="{DataTemplate local:Page1}" />
</Tab>
<Tab Title="Page2" Route="page2" Icon="page2.png">
<ShellContent Route="page2A" ContentTemplate="{DataTemplate local:Page2A}" />
<ShellContent Route="page2B" ContentTemplate="{DataTemplate local:Page2B}" />
</Tab>
<Tab Title="Page3" Route="page3" Icon="page3.png">
<ShellContent ContentTemplate="{DataTemplate local:Page3}" />
</Tab>
</TabBar>
I want the content of the page2 tab to be programatically determined using GoToAsync("tabs/page2/page2A") and GoToAsync("tabs/page2/page2B").
This way there should be persistence when the user navigates between tabs as to which ShellContent is displayed (e.g. page2A or page2B).
The behaviour works fine, but I want to hide the TOP Tab Bar that allows the user to navigate between the two ShellContent pages. Is there a way to do that in Xamarin.Forms Shell?
I can't find a way to do this with routes. The desired behaviour can be achieved with:
(Shell).CurrentItem.Navigation.PushAsync({desired_content});
By pushing onto the CurrentItem's Navigation the content within a tab can be updated, and will persist while the user navigates between bottom-bar tabs.

ViewModel is not getting called first time in master details page in Xamarin forms with prism

I am using Master details page in my application. I have used Prism in my application.
First time my details page view model is not getting called and due to this page is showing as empty.
<?xml version="1.0" encoding="UTF-8"?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:InforConcierge.Views"
x:Class="InforConcierge.Views.MainPage">
<MasterDetailPage.Master>
<local:LeftMenuPage x:Name="masterPage" Icon="home.png"/>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage x:Name="NavPage" BarBackgroundColor="{DynamicResource appColor}" >
<x:Arguments>
<local:HomePage />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
In master page i have "Home","Contacts" options.
Note: If I switch to another menu item("Contacts") and the select "Home" in menu page, then my view model of Home page is getting called.
You are directly creating an HomePage object from XAML. As far as I know, Prism is not able to intercept this and hence no viewmodel is created. You'll have to navigate to the page in order to enable Prism to auto-resolve the VM. We are loading our main view by calling
NavigationService.NavigateAsync("/MenuViewWrapper/NavigationRootPage/HomePage");
from App.OnInitialized. Please note that MenuViewWrapper (which would be your MainPage) and NavigationRootPage (which can be replaced by NavigationPage in your example) have to be registered for navigation (see here).

Resources