Set default tab on Xamarin Forms Shell

Viewed 4760

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.

3 Answers

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