Very short version is I want to, in code, make the shell go to where it was, and how it looked, when it first displayed on app start.
I have a xamarin.forms.shell page which shows a number of content pages using flyout and tabs. When the shell initially loads, it shows the first flyout item content page, which is my "main activity/page" with the most common UI.
If I go to another flyout item content page, I would like the backbutton to navigate to the "main flyout" and only if back button is clicked on this "main flyout", should it leave the app.
While I can intercept the backbutton and navigate to other pages, it does not have the effect of clicking the "main page" flyout. If I do
Shell.Current.GoToAsync(name of route to my main flyout);
I do get to that main page, but as fullscreen and the flyout menu, toolbar and tabs are gone.
For this you need to override the Back button behavior, in your desired content page by defining a command that will be fired when the user pressed the back button in that page and then navigate to your root page by it defined root:
CatsPage.Xaml
<Shell.BackButtonBehavior>
<BackButtonBehavior Command="{Binding BackCommand}"/>
</Shell.BackButtonBehavior>
Code-Behind or ViewModel
public ICommand BackCommand { get; private set; }
public CatsPage() //or VM constructor
{
...
BackCommand = new Command(async (x) => await Shell.Current.GoToAsync("///MainRoute"));
}
If you are using this content page as a Tab
content in more than one FlyoutItem
, but you only want this behavior to work on the the ContentPage
residing in the first FlyoutItem
you may add a conditional test based on page absolute route or Title
property:
Xaml example from jiang answer:
<FlyoutItem Route="MainRoute"
Title="Animals"
FlyoutDisplayOptions="AsMultipleItems">
<Tab Title="MainPage"
Route="MainPage"
Icon="paw.png">
<ShellContent Route="cats"
Style="{StaticResource DomesticShell}"
Title="Cats"
Icon="cat.png"
ContentTemplate="{DataTemplate views:CatsPage}" />
<ShellContent Route="dogs"
Style="{StaticResource DomesticShell}"
Title="Dogs"
Icon="dog.png"
ContentTemplate="{DataTemplate views:DogsPage}" />
</Tab>
<ShellContent Route="PageTwo"
Style="{StaticResource MonkeysShell}"
Title="Monkeys"
Icon="monkey.png"
ContentTemplate="{DataTemplate views:MonkeysPage}" />
<ShellContent Route="cats"
Style="{StaticResource DomesticShell}"
Title="Cats2"
Icon="cat.png"
ContentTemplate="{DataTemplate views:CatsPage}" />
</FlyoutItem>
Code-Behind or ViewModel
public CatsPage() //or VM constructor
{
...
BackCommand = new Command(async (x) => {
if (Shell.Current.CurrentState.Location.ToString().Equals("//MainRoute/MainPage/Cats"))
//popup to quit
else if (Shell.Current.CurrentState.Location.ToString().Equals("//MainRoute/Cats"))
await Shell.Current.GoToAsync("///MainRoute");
// or use to go back to previous: await Shell.Current.GoToAsync("..");
});
}
Once again you need to properly define and use your Tab
s and FlyoutItem
routes hierarchy otherwise it will result in an exception.