I've been trying to achieve hiding Top Navigations Bar in one of the shell tabs with no success.
I tried following this Tutorial with no success (might be outdated ?).
Here is my code :
<Shell
x:Class="Smogon_MAUIapp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Smogon_MAUIapp"
Shell.FlyoutBehavior="Disabled">
<!--Main Page-->
<TabBar>
<Tab Icon="Resources/navbar/smogon.png" Shell.NavBarIsVisible="False" >
<ShellContent
Shell.NavBarIsVisible="False"
NavigationPage.HasNavigationBar="False"
ContentTemplate="{DataTemplate local:Pages.MainPage}"
Route="MainPage">
</ShellContent>
<ShellContent
Shell.NavBarIsVisible="False"
NavigationPage.HasNavigationBar="False"
ContentTemplate="{DataTemplate local:Pages.Forum}"
Route="Forum"/>
<ShellContent
Shell.NavBarIsVisible="False"
NavigationPage.HasNavigationBar="False"
ContentTemplate="{DataTemplate local:Pages.SubForum}"
Route="SubForum"/>
<ShellContent
Shell.NavBarIsVisible="False"
NavigationPage.HasNavigationBar="False"
ContentTemplate="{DataTemplate local:Pages.Thread}"
Route="Thread"/>
</Tab>
<Tab Icon="Resources/Images/search.png" Shell.NavBarIsVisible="False">
<ShellContent
ContentTemplate="{DataTemplate local:Pages.Search}"
Route="Search">
</ShellContent>
</Tab>
<Tab Icon="Resources/Images/snorlax.png" Shell.NavBarIsVisible="False">
<ShellContent
ContentTemplate="{DataTemplate local:Pages.Profile}"
Route="Profile" />
</Tab>
<Tab Icon="Resources/Images/showdown.png" Shell.NavBarIsVisible="False">
<ShellContent
ContentTemplate="{DataTemplate local:Pages.Showdown}"
Route="Showdown" />
</Tab>
</TabBar>
</Shell>
and the code behind :
public partial class AppShell : Shell
{
public AppShell()
{
Routing.RegisterRoute("Home", typeof(MainPage));
Routing.RegisterRoute("Forum", typeof(Forum));
Routing.RegisterRoute("SubForum", typeof(SubForum));
Routing.RegisterRoute("Thread", typeof(Smogon_MAUIapp.Pages.Thread));
Routing.RegisterRoute("Search", typeof(Search));
Routing.RegisterRoute("Profile", typeof(Profile));
Routing.RegisterRoute("ShowDown", typeof(Showdown));
InitializeComponent();
}
}
Here is a screenshot of what I am getting and what I'd like :
Gotten result Vs Wanted one
Help would be appreciated ! =)
I tried removing the top bar of one of my tabs in my shell. But i could only remove the titles and the bar is still there.
Update 1 :
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Smogon_MAUIapp.Pages.Forum"
Title="Forum"
Shell.NavBarIsVisible="False">
<VerticalStackLayout>
</VerticalStackLayout>
</ContentPage>
I did that but it didn't change anything =)
In your Pages, e.g. your Forum.xaml, you could set Shell.NavBarIsVisible="False" to hide the navigation bar, e.g.:
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
Shell.NavBarIsVisible="False">
<!-- ... -->
</ContentPage>
This should be done in the ContentPage. It works fine for me like that using tabs:
Side note: NavigationPage is not supported when using Shell, therefore you can safely remove NavigationPage.HasNavigationBar="False" from your Shell definition, because it's obsolete.
This is NOT the NavigationBar on the picture.
Actually, your code is working perfectly and the bar is hidden.
Each Tab is ShellSection, and if this ShellSection has more than one Item in the list of ShellContents, this bar appears, so change between them becomes possible.
If you want, you can change your XAML to "true" and you will see another blue line appear above the one you are concerned about.
This will be the actual NavigationBar.
This aside, what really bothers me is why you add several ShellContents, and want to remove the only way to switch between them.
If you want custom navigation, you do not have to put them inside the TabBar. You can put them under it (just like separate Shell Items) and then navigate to them normally.
Edit: Please notice in the accepted answer of the link you gave, how the programmer is not adding every single ShellContent at once, but is using custom navigation events, and using a reference of its Tab for adding/removing them one by one, so that this bar does not render.
Related
This is my AppShell XAML file (not sure this is right):
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MauiUI.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiUI"
xmlns:pages="clr-namespace:MauiUI.Pages"
FlyoutHeaderBehavior="CollapseOnScroll"
FlyoutBackdrop="Silver">
<FlyoutItem Title="Amazons of Volleyball">
<ShellContent Title="Amazons of Volleyball"
Route="home"
ContentTemplate="{DataTemplate pages:MainPage}" />
</FlyoutItem>
<FlyoutItem Title="Add new Amazon">
<ShellContent Title="Add new Amazon"
Route="add-or-update"
ContentTemplate="{DataTemplate pages:AddOrUpdatePlayer}" />
</FlyoutItem>
<ShellContent Title="Amazons of Volleyball"
IsVisible="False"
ContentTemplate="{DataTemplate pages:SplashPage}"
Route="splash" />
</Shell>
Now the hamburger menu is appearing, but to see the content I had to drag over it my mouse and pull from left to right it to appear.
I am on Android emulator in windows.
You can add Shell.FlyoutBehavior="Flyout" to your AppShell.
Here is the example:
<Shell
x:Class="MauiApp15.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiApp15"
Shell.FlyoutBehavior="Flyout"
>
I want to add a second set of tabs on a page that is accessed through tabs defined in AppShell in my .NET MAUI app. According to the documentation, TabbedPage is not compatible with .NET MAUI apps that use AppShell. How do I achieve this -- preferably with standard XAML and not through a third party solution.
Here's the look I want:
As mentioned, I define my tabs in AppShell like this:
<FlyoutItem Title="Home" Icon="home.png">
<Tab Title="Tiger" Icon="tiger.png">
<ShellContent Route="Tiger" ContentTemplate="{DataTemplate local: Tiger}" />
</Tab>
<Tab Title="Giraffe" Icon="giraffe.png">
<ShellContent Route="Giraffe" ContentTemplate="{DataTemplate local: Giraffe}" />
</Tab>
<Tab Title="Moose" Icon="moose.png">
<ShellContent Route="Moose" ContentTemplate="{DataTemplate local: Moose}" />
</Tab>
<Tab Title="Elephant" Icon="elephant.png">
<ShellContent Route="Elephant" ContentTemplate="{DataTemplate local: Elephant}" />
</Tab>
</FlyoutItem>
If I understand your question correctly, you just need to add additional <ShellContent> elements inside your <Tab> definitions as described in the docs:
<FlyoutItem Title="Home" Icon="home.png">
<Tab Title="Tiger" Icon="tiger.png">
<ShellContent Route="Tiger" ContentTemplate="{DataTemplate local: Tiger}" />
<ShellContent Route="Tiger2" ContentTemplate="{DataTemplate local: Tiger2}" />
<ShellContent Route="Tiger3" ContentTemplate="{DataTemplate local: Tiger3}" />
</Tab>
<Tab Title="Giraffe" Icon="giraffe.png">
<ShellContent Route="Giraffe" ContentTemplate="{DataTemplate local: Giraffe}" />
</Tab>
<Tab Title="Moose" Icon="moose.png">
<ShellContent Route="Moose" ContentTemplate="{DataTemplate local: Moose}" />
</Tab>
<Tab Title="Elephant" Icon="elephant.png">
<ShellContent Route="Elephant" ContentTemplate="{DataTemplate local: Elephant}" />
</Tab>
</FlyoutItem>
I don't know if this works together with the <FlyoutItem>, though.
You can not.
You can use this auto wrapping, and get confused all you want.
But in the end, it all gets to the point, where your TabBar (that is Shell Item), contains Tabs (that are Shell Sections) and those contain a list of Shell Contents.
You can navigate between Items, and the Shell itself will provide means to navigate between Sections and Contents.
But those are not tabs.
I would like to change the color of a specific Tab in a .Net MAUI TabBar. I've been able to change the whole TabBarBackgroundColor as below. But how can I override the color of a single Tab? For example if I wanted the BackgroundColor of "TAB 2" to be Bisque.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MyApp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
Shell.FlyoutBehavior="Disabled"
Shell.TabBarBackgroundColor="AliceBlue" >
<TabBar IsVisible="True"
IsEnabled="True"
>
<ShellContent
Shell.TabBarIsVisible="True"
Title="TAB 1"
ContentTemplate="{DataTemplate local:MainPage}"/>
<ShellContent
Shell.TabBarIsVisible="True"
Title="TAB 2"
ContentTemplate="{DataTemplate local:MainPage}"/>
</TabBar>
</Shell>
I believe that platform-specific code may be needed. I'm targeting iOS and Android.
I have a .net maui application with AppShell that defines a tabbar with this code:
<TabBar>
<Tab Title="{x:Static resources:Strings.HomeTitle}">
<Tab.Icon>
<FontImageSource FontFamily="MaterialIconsRound" Glyph="home" />
</Tab.Icon>
<ShellContent>
<dashboard:DashboardPage />
</ShellContent>
</Tab>
<Tab Title="{x:Static resources:Strings.StatisticsTitle}">
<Tab.Icon>
<FontImageSource FontFamily="MaterialIconsRound" Glyph="donut_small" />
</Tab.Icon>
<ShellContent Title="{x:Static resources:Strings.StatisticsTitle}">
<statistics:StatisticSelectorPage />
</ShellContent>
</Tab>
<Tab Title="{x:Static resources:Strings.MoreTitle}">
<Tab.Icon>
<FontImageSource FontFamily="MaterialIconsRound" Glyph="more_horiz" />
</Tab.Icon>
<ShellContent>
<overflowMenu:OverflowMenuPage />
</ShellContent>
</Tab>
</TabBar>
On Android the icons do change correctly the color depending on the device theme or when they are selected. On iOS only the text changes.
Is that a bug or do I have to set a specific style for that?
There is a known issue about this problem. And this issue has been moved to the Backlog milestone.
You can follow it up here: https://github.com/dotnet/maui/issues/8244 .
Thanks for your support and feedback for maui.
In Xamarin Forms Shell, the content of AppShell.xaml is:
<Shell ...>
<ShellContent Route="login" ContentTemplate="{DataTemplate local:LoginPage}" />
<TabBar Route="home">
<ShellContent Route="Tab1" ContentTemplate="{DataTemplate home:Tab1Page}" Title="tab1" />
<ShellContent Route="Tab2" ContentTemplate="{DataTemplate home:Tab2Page}" Title="Tab2" />
</TabBar>
</Shell>
The login page is displayed first.
After user1 logs in, the tabs are displayed with user1 content. The login page is not destroyed (why?).
After logout the login page is displayed again. The page is not recreated as it was not destroyed at first. Also the tabs are not destroyed (why?).
Then user2 logs in: the tabs are displayed again, but not recreated. They still display user1's content.
After login i'm using this code to force remove the login page from the navigation stack:
foreach (var page in Shell.Current.Navigation.NavigationStack.Reverse().Where(p => p != null))
Shell.Current.Navigation.RemovePage(page);
await Shell.Current.GoToAsync($"//home/Tab1");
I'm using Shell.Current.GoToAsync("//login"); after logout.
It seems the issue is caused by the static declaration in AppShell.xaml which caches all the created pages.
What's the correct way to implement that common scenario ? (i'm not using any flyout)
For this,I think you can refer to article Creating a login flow with Xamarin Forms Shell.
The Shell is structured as follows:
<Shell>
<!-- Loading/Start Page -->
<ShellItem Route="loading">
<ShellContent ContentTemplate="{DataTemplate local:LoadingPage}" />
</ShellItem>
<!-- Login and Registration Page -->
<ShellContent Route="login"
ContentTemplate="{DataTemplate local:LoginPage}">
</ShellContent>
<!-- Main Page -->
<FlyoutItem Route="main"
FlyoutDisplayOptions="AsMultipleItems" IsTabStop="False">
<ShellContent Route="home"
IsTabStop="False"
ContentTemplate="{DataTemplate local:MainPage}"
Title="Home" />
</FlyoutItem>
<MenuItem Text="Logout"
Command="{Binding ExecuteLogout}" />
</Shell>
For the login page, we would set it like this:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
...
Shell.PresentationMode="ModalAnimated"
...>
...
</ContentPage>
And whenever you navigate modally, it is always a good idea to override the back button navigation in the code behind of the target page as follows:
protected override bool OnBackButtonPressed()
{
return true;
}
And there is a sample included in above article, you can check it here.