Set default tab on Xamarin Forms Shell - xamarin.forms

How to set the default selected Tab inside the tab bar on Xamarin forms shell?
<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestApp.NavigationShell"
xmlns:pages="clr-namespace:TestApp.Pages"
xmlns:pageModels="clr-namespace:TestApp.PageModels">
<TabBar Route="testapp">
<Tab Title="Saved" Icon="tabDashboard" Route="dashboard"><ShellContent ContentTemplate="{DataTemplate pages:DashBoardPage}"/></Tab>
<Tab Title="Calendar" Icon="tabCalendar" Route="calendar"><ShellContent ContentTemplate="{DataTemplate pages:CalendarPage}"/></Tab>
<Tab Title="Search" Icon="tabSearch" Route="search"><ShellContent ContentTemplate="{DataTemplate pages:SearchPage}"/></Tab>
<Tab Title="Support" Icon="tabSupport" Route="support"><ShellContent ContentTemplate="{DataTemplate pages:SupportPage}"/></Tab>
<Tab Title="Profile" Icon="tabAccount" Route="account"><ShellContent ContentTemplate="{DataTemplate pages:AccountPage}"/></Tab>
</TabBar>
According to the Xamarin Forms documentation, the first Shell Content will be the default content on the screen. However; I'm trying to set the "Search" page as the default tab rather than "Saved".
I tried to set Tab Index - no luck
I also tried to call routing on onAppearing method of Shell but seems like Shell's on appearing method never gets fired.
I tried to navigate to Search as well:
public partial class NavigationShell : Shell
{
public NavigationShell()
{
InitializeComponent();
//Shell.Current.TabIndex = 2;
}
protected override async void OnAppearing()
{
base.OnAppearing();
//await Shell.Current.GoToAsync("testapp/search");
}
}
What could be the best solution that when app opens need to set the default tab?
Thank you.

Here, how I fix it by using the Name field attribute.
I assigned the name to the TabBar and the tab which I want to assign in the first place.
AppShell.xaml
<TabBar x:Name="main_tab_bar" Route="main">
<Tab Title="History">
<Tab.Icon>
<FontImageSource FontFamily="MaterialIconsRegular" Glyph="{x:Static Emojis:MaterialRegFont.List}"/>
</Tab.Icon>
<ShellContent ContentTemplate="{DataTemplate Views:CallLogPage}" />
</Tab>
<Tab x:Name="main_tab_bar_dial" Title="Dial" >
<Tab.Icon>
<FontImageSource FontFamily="MaterialIconsRegular" Glyph="{x:Static Emojis:MaterialRegFont.Dialpad}"/>
</Tab.Icon>
<ShellContent ContentTemplate="{DataTemplate Views:MainDialerPage}" />
</Tab>
<Tab Title="Settings">
<Tab.Icon>
<FontImageSource FontFamily="MaterialIconsRegular" Glyph="{x:Static Emojis:MaterialRegFont.Settings}"/>
</Tab.Icon>
<ShellContent ContentTemplate="{DataTemplate Views:MainSettingsPage}" />
</Tab>
</TabBar>
AppShell.cs
public AppShell() {
InitializeComponent();
Init();
}
private void Init() {
main_tab_bar.CurrentItem = main_tab_bar_dial;
}

Nevermind, I think I found a solution.
public Page Init(Shell root)
{
CurrentShell = root;
root.CurrentItem.CurrentItem = root.CurrentItem.Items[2];
return CurrentShell;
}
Becase my shell have ONLY one root item which is tabbar itself. I just get the search tab and assigned to the first child's current item and it worked.
Please post your answers if you found another way around.
Thank you.

On the constructor of your Shell class you can set the CurrentItem
in my case I have an <ShellItem> with some <tab>
public PrivateShell()
{
InitializeComponent();
this.CurrentItem.CurrentItem = homeTab; //tab defined by x:Name on XAML
}
As far as I could check it does not pre-render the first shellcontent in case you're using ContentTemplate pattern

Related

Keyboard flashes when navigating in Shell flyouts

My Xamarin.Forms app is using Shell flyouts for navigation. When I navigate the app on iOS, I notice a strange behaviour. Reproduction steps:
Go to a page that has an Entry in it
Type anything into the Entry
Go to another page
Return to the same page you typed something into the Entry
The keyboard then pops up and then disappears right after. I can see the cursor in the Entry appear then disappear too. I removed a lot of my code to try to find the problem, but I can not find it. My code:
AppShell.xaml:
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyApp.Views"
Title="MyApp"
x:Name="shellAppShell"
x:Class="MyApp.AppShell">
<FlyoutItem x:Name="flyoutItemMainPage" Title="Home" Icon="icon_about.png">
<ShellContent x:Name="shellContentMainPage" Route="MainPage" ContentTemplate="{DataTemplate local:MainPage}" />
</FlyoutItem>
<FlyoutItem x:Name="flyoutItemAPage" Title="A Page" Icon="Pagea.png">
<ShellContent x:Name="shellContentPageA" Route="PageA" ContentTemplate="{DataTemplate local:PageA}" />
</FlyoutItem>
<!-- More flyouts... -->
</Shell>
PageA.xaml:
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Name="PageA"
x:Class="MyApp.Views.PageA">
<ContentPage.Content>
<StackLayout Orientation="Vertical" >
<Entry />
<Button Text="back" Clicked="OnBackClicked"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
PageA.xaml.cs
public partial class PageA : ContentPage
{
public PageA()
{
InitializeComponent();
}
void OnBackClicked(object sender, EventArgs e)
{
Shell.Current.CurrentItem = AppShellGlobal.ShellContentMainPage;
}
}
After my testing, this situation only occurs in iOS.
There is a simpler solution, you can rewrite the ContentPage and end the editing state of the page when the page loads.
First, create the MyPageRenderer class in your project's xxx.iOS directory.
Here is the internal code:
[assembly: ExportRenderer(typeof(ContentPage), typeof(MyPageRenderer))]
namespace App15.iOS
{
public class MyPageRenderer : PageRenderer
{
public override void ViewDidAppear(bool animated)
{
View.EndEditing(true);//Solved the problem with this line of code
base.ViewDidAppear(animated);
}
}
}
Here is the screenshot:

TabbedPage selectedItem doesn't change when change tab programmatically to tab in "More"

I am working on a Xamarin Forms app with a TabbedPage which has 6 tabs.
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:tabs="clr-namespace:TabbedPageIssue"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:TabbedPage.ToolbarPlacement="Bottom"
android:TabbedPage.IsSwipePagingEnabled="False"
android:TabbedPage.BarSelectedItemColor="#F79320"
android:TabbedPage.BarItemColor="#B1B2B3"
x:Class="TabbedPageIssue.MainPage">
<tabs:Tab1 Title="Tab1"/>
<tabs:Tab2 Title="Tab2"/>
<tabs:Tab3 Title="Tab3"/>
<tabs:Tab4 Title="Tab4"/>
<tabs:Tab5 Title="Tab5"/>
<tabs:Tab6 Title="Tab6"/>
</TabbedPage>
In my app, I want to have a button to direct the app to a tab "inbox" in the "More" part with this code:
private void Button_Clicked(object sender, EventArgs e)
{
var mainPage = this.Parent as TabbedPage;
mainPage.CurrentPage = mainPage.Children[4];
}
When i click the button to change tab, the View changes but the "More" tab is not selected, and if i click on tab1, the view of tab 5 doesn't disappear.
This seems to be a bug of TabbedPage. Everybody has any idea to fix this problem?
I was able to reproduce this issue. For workaround, you could use Shell tabs instead. For the latest version of VS, when you create a Tabbed template, it is using Shell. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/
Xaml:
<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App3.Views"
Title="App3"
x:Class="App3.AppShell">
<TabBar>
<ShellContent Title="Tab1" ContentTemplate="{DataTemplate local:Page1}" />
<ShellContent Title="Tab2" ContentTemplate="{DataTemplate local:Page2 }" />
<ShellContent Title="Tab3" ContentTemplate="{DataTemplate local:Page3 }" />
<ShellContent Title="Tab4" ContentTemplate="{DataTemplate local:Page4}" />
<ShellContent Title="Tab5" Route="page5" ContentTemplate="{DataTemplate local:Page5 }" />
<ShellContent Title="Tab6" ContentTemplate="{DataTemplate local:Page6 }" />
</TabBar>
</Shell>
Navigating from Page1 to Page5:
async void Button_Clicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync("//page5");//page5 is the route i set in xaml
}
OutPut:

Xamarin Shell FlyoutItem's tab click event

Im using Xamarin forms, and on my AppShell, i want 2 tabs, i want to have a clicked event on one of the tabs, so that when clicked on it doesnt load another page but actually execute a function (show an Rg.Popup on top of the current page).
So i need a way to capture the tab clicked event or maybe a command or anything.
here is what i have:
<FlyoutItem FlyoutDisplayOptions="AsSingleItem" IsVisible="False">
<Tab Title="001">
<ShellContent ContentTemplate="{DataTemplate local:HomePage}"></ShellContent>
</Tab>
<Tab Title="002">
<ShellContent ContentTemplate="{DataTemplate local:ProfilePage}"></ShellContent>
</Tab>
</FlyoutItem>
1 year too late but hope this helps. you can use menuItem which will display ontop of flyoutitem
<MenuItem Text="item" StyleClass="MenuItemLayoutStyle" Clicked="OnClickMethod">
</MenuItem>
Create a class inherit from TabBar and override the method OnPropertyChanged:
public class MyTab : TabBar
{
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (propertyName == "CurrentItem")
{
int index = this.Items.IndexOf(this.CurrentItem);
if(index == 0)
{
}
if(index == 1)
{
}
}
}
}
Use it in Xaml
<local:MyTab>
<Tab Title="Browse" Icon="tab_feed.png" x:Name="tab1">
<ShellContent ContentTemplate="{DataTemplate local:ItemsPage}" />
</Tab>
<Tab Title="About" Icon="tab_about.png">
<ShellContent ContentTemplate="{DataTemplate local:AboutPage}" />
</Tab>
</local:MyTab>
Another way I thought is that you can execute the function in the page's OnAppearing method.

Login user and navigation back to home page Shell

I am using Shell in my Xamarin forms application,
I have an issue when My user registers successfully he is redirected to Homepage, however there is no Tab Menu on the bottom while if I redirect him to AppShell the page is blank. Do you have any suggestions?
My redirection
await App.Current.MainPage.Navigation.PushModalAsync(new AppShell());
My AppShell
<TabBar >
<Tab x:Name="HomePage" Icon="home.png" Title="{x:Static resources:AppResources.LabelHome}" >
<ShellContent ContentTemplate="{DataTemplate views:HomePage}"/>
</Tab>
<Tab x:Name="Categories" Icon="collections.png " Title="{x:Static resources:AppResources.LabelCategory}">
<ShellContent ContentTemplate="{DataTemplate views:CategoriesPage}"/>
</Tab>
<Tab x:Name="Add" Icon="add.png" Title="{x:Static resources:AppResources.LabelAddingPage}">
<ShellContent ContentTemplate="{DataTemplate views:AddingPage}"/>
</Tab>
<Tab x:Name="Inbox" Icon="mail.png" Title="{x:Static resources:AppResources.LabelInbox}" >
<ShellContent ContentTemplate="{DataTemplate views:InboxPage}"/>
</Tab>
<Tab x:Name="Profile" Icon="userg.png" Title="{x:Static resources:AppResources.LabelProfil}">
<ShellContent ContentTemplate="{DataTemplate views:UserProfilePage}"/>
</Tab>
</TabBar>
And my app
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
from your redirection await App.Current.MainPage.Navigation.PushModalAsync(new AppShell()); , i think you have another Shell Application just for your login.
try await App.Current.MainPage = new AppShell(); to initialize the Shell as your mainPage.
hope this helps ;)
You will have to make the following changes :-
Your redirection should be :-
await Shell.Current.GoToAsync("//main");
Your App Shell should have this :-
<TabBar Route="main">
...
</TabBar>
Hopefully this helps.

How do i navigate to a shell tabbed page from a parent shell tabbed page

i have a parent shell tabbed page. i want to be able to navigate from one of the contentPage of this parent page to another shell tabbed page.
Navigation can be performed by specifying a valid absolute URI as an argument to the GoToAsync method: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/navigation#perform-navigation
On OnItemSelected method, invoke the code below.
await (App.Current.MainPage as Xamarin.Forms.Shell).GoToAsync("//tabbar/tab/about", true);
AppShell.xaml: Set the route.
<TabBar Route="tabbar">
<Tab Title="Browse" Icon="tab_feed.png">
<ShellContent ContentTemplate="{DataTemplate local:ItemsPage}" />
</Tab>
<Tab Title="About" Icon="tab_about.png" Route="tab">
<ShellContent Route="about" ContentTemplate="{DataTemplate local:AboutPage}" />
</Tab>
</TabBar>

Resources