I have specified a trival page structure in a Xamarin Shell v5 app. I have a flyout with flyout items in the following structure:
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent>
<local:MainPage...
</ShellContent>
<ShellContent>
<local:Page1...
</ShellContent>
<ShellContent>
<local:Page2...
</ShellContent>
</FlyoutItem>
When I start the app the MainPage is displayed as default. So far so good.
The flyout displays the three pages. Also good.
When I tap on the Page2 flyout, that page is displayed. But a navigation stack isn't created, meaning it also displays the hamburger menu (instead of the back button where the hamburger icon is).
I would like to have Page2 be a "child page" (navigation-wise) so that when a user taps the Page2 flyout a back button is displayed at the top so the user can go back to the Homepage.
I've been reading the documentation backwards and forwards, and can't figure out how to do this in the visual shell hierarchy.
I assume it has to do with routes, but I'm not sure how to specify routes so Page2 becomes a 'sub-page' (or whatever the word is).
Does anyone know how to do this? This applies to both iOS and Android.
I would prefer not to have the tabs displayed at the bottom of the screen as I've seen in many examples. Just a neat, clean flyout menut.
If the pages are still in the Shell hierachical structure(the page2 in the FlyoutItem), the hamburger icon would show always.
You could use the code below to register the pages that do not exist in the Shell visual hierachy. And then when you navigate to these pages, you could use the back button to go back.
Routing.RegisterRoute("page2", typeof(Pages));
Navigate:
await Shell.Current.GoToAsync("page2");
In the end I solved it by using MenuItems instead of FlyoutItems. In the callback for each MenuItem I call Shell.Current.GoToAsync(""); which opens the page as a child, i.e. back navigation can be performed.
And since menu items can be styled (just like flyout items), it looks nice on the device. It's a workaround, but one I'm happy with.
Related
If I navigate to other pages from the Shell menu items then I have the option to open the pull-out menu again.
And if I go to the page from the code inside, then the menu button at the top left is no longer there.
await Shell.Current.GoToAsync("step");
How to open a page from the code and what would be in the open page was the shell menu button?
If you navigate to the page that exists as part of the Shell visual hierarchy and register the route like below.
<ShellContent
Title="Page1"
ContentTemplate="{DataTemplate local:Page1}"
Icon="tab_about.png"
Route="about" />
It could navigate with the parameter like below.
await Shell.Current.GoToAsync("//about");
When you navigate, the hamburger icon would still be there.
If you navigate to the page that not exist in Shell visual hierarchy and register using Routing.RegisterRoute, it would cover all the page and the hamburger icon would not show. But you could back to the Shell with the back button on top left.
Routing.RegisterRoute("step", typeof(Page2));
The edit queue is always full! So here is my expansion of Wendy's answer:
TLDR:
Essentially the Hamburger Nav is only visible on Pages that are added or registered to the Shell or one of its child BaseShellItems and thus are apart of the Shell Visual Hierarchy ->
If the Page is registered via AppShell.xaml (can also be added programmatically) then the Page is being added to a BaseShellItem and is apart of the Shell Visual Hierarchy.
There are several ways to register a page for navigation and that determines whether the page is displayed with a hamburger:
If register a page via the AppShell.xaml like:
<ShellContent
Title="This is Page1"
ContentTemplate="{DataTemplate local:Page1}"
Icon="tab_about.png"
Route="Page1" />
you can navigate with the parameter like below.
await Shell.Current.GoToAsync("//Page1");
When you navigate, the hamburger icon would still be there, as the page is added to a BaseShellItem( BaseShellItem->ShellContent).
If you register a page not in the AppShell.xaml but via Routing:
Routing.RegisterRoute(nameof(page1), typeof(Page1));
and navigate to the page, it would cover all the page and the hamburger icon would not show, as its not added to a BaseShellItem. But you could go back to the Shell with the back button on top left.
You can register the Page (as of Xamarin.Forms 5) by adding it to a BaseShellItem but not have it shown in the Shell's menus and get the page to have have the hamburger nav menu by adding it as to a FlyoutItem in the AppShell.xaml and using FlyoutItemIsVisible="False":
<FlyoutItem
Title="Stat Page"
FlyoutItemIsVisible="False"
IsEnabled="True">
<ShellContent
Title="Page1"
ContentTemplate="{DataTemplate local:Page1}"
Icon="tab_about.png"
Route="about" />
</FlyoutItem>
Quick question,
In Xamarin Forms, when using a Tabbed Page, is there any way for there to be content that remains static between the tabs (other than the tabbar itself)?
For example, if I have a TabbedPage with 3 children (say Page1, Page2 and Page3), can I add other children to TabbedPage that are not a part of the tab itself, but elsewhere, and stay there between tabs?
My use for this is I have 3 tabs in my TabbedPage, which is are at the bottom of the page. I would like a settings button in the top-right of each page, without having to create the same content multiple times in each page that is a child of the TabbedPage.
<TabbedPage xlmns="...>
[Content Here that remains between all tabs, but not a part of the tabbar itself]
<local:Page1>
<local:Page2>
<local:Page3>
</TabbedPage>
Is there some way of doing this easily? Or is there some other method?
Thanks for any help.
You need to check this and create your own control template
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/templates/control-templates/
I would like a settings button in the top-right of each page, without having to create the same content multiple times in each page that is a child of the TabbedPage.
An easy way is using custom control as model. Add the custom control, the button would show in every tabbed pages(page1, page2, page3). If you want to more change on the button, change the custom model, all the changes would show in pages.
Custom Control: ButtonModel
<Button x:Name="btnModel" Text="Button" HorizontalOptions="EndAndExpand" Margin="4,0,8,0"></Button>
Add this in Page1, Page2, Page3
<local:ButtonModel ></local:ButtonModel>
There are a few methods of fixing this. One of these is outlined in another comment very well, however I found that the Xamarin Forms 'Pure' tabs fitted my needs better.
https://www.sharpnado.com/pure-xamarin-forms-tabs/
It was relatively intuitive once I got my head round it and handles integration with mvvm rather well. The tabs need nod span the entire page (other than the tabbar) which is exactly what I wanted.
I just new to Xamarin.Form with Prism. I want to load the page in different behavior. The first one I achieve already is in image below.
But I want to do a behavior like below image. Load a new page outside master detail page. How can I do it in prism?
You have figured out how to display the "Hamburger" icon as well as title by doing the following.
NavigationService.NavigateAsync("MasterPage/NavigationPage/DetailsPage")
If a user makes a selection from the actions listed on the master page. For Example, let's say settings.
You have a couple of options here, you can do navigate relatively
NavigationService.NavigateAsync("Settings")
This will navigate to the settings page. This will also display the back button as the second image. Your current page path will be
MasterPage/NavigationPage/DetailsPage/Settings
Now let's say you want the settings page to be the top details page. You have to navigate to it via an absolute path.
MasterPage/NavigationPage/Settings
NavigationService.NavigateAsync("MasterPage/NavigationPage/Settings")
You need to add a new page to the stack, page over existing one. To do that you should do navigation like this:
navigationService.NavigateAsync("Settings")
I am using the Prism.Forms.Unity
On drawer menu item selected user is navigating from MasterDetails page to next page, On the navigated page is not showing me that back arrow which will go back to my master details page.
I have tried using few options which are shown below
The first option I tried using the NavigationPage, starting the new page using prism navigation method
_navigationService.NavigateAsync("NavigationPage/Add");
The second option I tried to set the property in XAML
NavigationPage.HasBackButton="True"
These two ways are not working for me.
What is the correct way to this?
There is no back button if you only have one page on the NavigationPage's navigation stack. You need to have more than one page on the nav stack to have a back button. Otherwise, there is nothing to go back to.
What I want to do is to maintain the hamburger icon across all pages of my mobile app. So i've done this in my navigation service
private static async Task NavigateAsync<T>(T page) where T : Page
{
NavigationPage.SetHasBackButton(page, false);
NavigationPage.SetBackButtonTitle(page, "Atras");
await App.Navigator.PushAsync(page, true);
}
When I navigate to another page, back button isn't showing neither hamburger button.
So, how can I do to keep hamburger icon showing in navigation bar?
Thanks!
You should be using MasterDetail page to have a Hamburger Icon.
You will see the Hamburger icon as long as you are navigating between the detail pages.
But when you navigate away from the detail page via PushAsync or PushModalAsync you are in the Navigation of the detail page and you wont be able to see the Hamburger icon.
A work around possible is to deal the Navigation from detail page also as within the master-detail page or have all your pages be detail pages without any inner navigation.