I'm trying to use the newly introduced Shell object in Xamarin to do the navigation and the child pages but I'm stumbling up with some issues setting up the shell.
This is my markup:
<?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:pages="clr-namespace:App.Views.FLMobile"
FlyoutBehavior="Flyout"
x:Class="App.Views.FLMobile.AppShell">
<FlyoutItem Title="MyTabApp" Shell.TabBarIsVisible="False" FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Title="Bears" IsTabStop="true" Icon="" ContentTemplate="{DataTemplate pages:MainPage}" />
</FlyoutItem>
<ShellContent Title="About" ContentTemplate="{DataTemplate pages:MenuPage}" />
</Shell>
And the code behind:
namespace App.Views.FLMobile
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class AppShell : Xamarin.Forms.Shell
{
public AppShell()
{
InitializeComponent();
}
}
}
What am I doing wrong?
This is the error I'm getting:
System.ArgumentException: 'Active Shell Item not set. Have you added
any Shell Items to your Shell? Parameter name: ShellItem'
Are you using the latest version of Xamarin Forms?
If not I would suggest you upgrade to it as it has many bug fixes.
Secondly, the issue is that you are directly using the shell content without a flyout item
so what you actually need to do is something like:
<FlyoutItem Title="MyTabApp" Shell.TabBarIsVisible="False" FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Title="About" ContentTemplate="{DataTemplate pages:MenuPage}" />
</FlyoutItem>
Related
I'm implementing shell in my app and the shell content inside my ordersTab are by default positioned from left to right. My question how can I position it from right to left. FlowDirection doesn't work here. below is a sample code.
<TabBar >
<Tab Title="الطلبات" Shell.NavBarIsVisible="False" Icon="ic_box.png" x:Name="ordersTab">
<ShellContent Title="طلبات جديدة" x:Name="newOrders"
ContentTemplate="{DataTemplate local:PendingOrdersPage}" />
<ShellContent Title="طلبات قيد التنفيذ" x:Name="ordersInProcess"
ContentTemplate="{DataTemplate local:ProcessOrdersPage}"/>
</Tab>
<ShellContent Title="الرئيسة" Shell.NavBarIsVisible="False" x:Name="homePage"
ContentTemplate="{DataTemplate local:HomePage}"
Icon="ic_home.png"/>
</TabBar>
I bought this template and i want to use Command or Clicked event on tab section. When I clicked the tab it goes to the page but page created at once while program is on but i want to make control each time when page created. How can i use Command or Clicked event on tabbar.
<Tab Title="{x:Static res:AppResources.Home}" Route="home" >
<Tab.Icon>
<FontImageSource FontFamily="MaterialOutlined" Glyph="{x:Static md:Icons.Home}" />
</Tab.Icon>
<ShellContent ContentTemplate="{DataTemplate views:HomePage}" />
</Tab>
<Tab Title="{x:Static res:AppResources.Cart}" Route="cart" >
<Tab.Icon>
<FontImageSource FontFamily="MaterialOutlined" Glyph="{x:Static md:Icons.ShoppingCart}" />
</Tab.Icon>
<ShellContent ContentTemplate="{DataTemplate views:CartPage}" />
</Tab>
<Tab Title="{x:Static res:AppResources.MyAccount}" Route="myaccount">
<Tab.Icon>
<FontImageSource FontFamily="MaterialOutlined" Glyph="{x:Static md:Icons.Person}" />
</Tab.Icon>
<ShellContent ContentTemplate="{DataTemplate views:LoginPage}" />
</Tab>
</TabBar>
You can try to add a property changed event to the tabbar. Such as:
private void TabBar_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var tabbar = sender as TabBar;
if(tabbar.CurrentItem.TabIndex == 0)
{
}else if (tabbar.CurrentItem.TabIndex == 1)
{
}
}
In the shell.xaml:
<TabBar PropertyChanged="TabBar_PropertyChanged">
I have a folder named jsonarray containing Page3.xaml . I want to show this page calling it from AppShell.xaml. The ordinary method calling in AppShell.xaml is:
<TabBar>
<ShellContent Title="About" Icon="icon_about.png" Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
</TabBar>
I tried:
<TabBar>
<ShellContent Title="Page3" Icon="Page3.png" Route="Page3" ContentTemplate="{DataTemplate local:Page3}" />
</TabBar>
but it errors: " Cannot resolve type "Page3".
Any idea how do I call the Page3 from the jsonarray folder?
I put a lot of effort into research, but I can't not solve my issue.
What I want to achieve:
I would like to use Xamarin Shell Navigation and hide the Top Navigation Tabs (not title bar --> called "navbar", not "tabbar"). Watch out for the image and the orange marked section.
Shell.TabBarIsVisible="False" hides Bottom "TabBar" ("Tab 1", "Tab 2", "Tab 3")
Shell.NavBarIsVisible="False" hides Title Bar ("Page 1 Full Title")
Nothing hides the Top Navigation Tabs below that Title Bar
That is my structure:
<Shell>
<TabBar x:Name="RootTab">
<Tab
Title="Tab1" >
<ShellContent
Route="page1"
Title="page1"
ContentTemplate="{DataTemplate view:Page1}" />
<ShellContent
Route="page2"
Title="page2"
ContentTemplate="{DataTemplate view:Page2}" />
<ShellContent
Route="page3"
Title="page3"
ContentTemplate="{DataTemplate view:Page3}" />
<ShellContent
Route="page4"
Title="page4"
ContentTemplate="{DataTemplate view:Page4}" />
</Tab>
<Tab
Title="Tab2" >
<ShellContent
Route="tab2"
Title="tab2"
ContentTemplate="{DataTemplate view:Tab2Page}" />
</Tab>
<Tab
Title="Tab3" >
<ShellContent
Route="tab3"
Title="tab3"
ContentTemplate="{DataTemplate view:Tab3Page}" />
</Tab>
</TabBar>
</Shell>
What i tried?
IsTabStop
Just placing 1 starting ShellContent (Page 1) in Tab 1 and then manually adding/removing pages (2, 3, 4) via code. That works fine for android. But iOS is showing just a black page after adding the new page and removing the old page from Tab 1.
Placing ShellContents outside of TabBar. But then I loose my TabBar...
Shell Image: https://i.stack.imgur.com/WYugb.png
UPDATE:
This works in Android but not in iOS (black page):
Having only one ShellContent in XAML and adding other manually in Code
AppShell.mytab.Items.Add(shell1);
AppShell.mytab.Items.Remove(shell0);
When I add the this line in the middle:
Shell.Current.CurrentItem.Items[0].CurrentItem = shell1; (Items[0] means first tab of TabBar --> "Tab 1")
It looks like it works, hurray! and showing the next page but it produces an error:
System.NullReferenceException: 'Object reference not set to an instance of an object'
ShellSectionRootRenderer.cs:201
Seems like https://github.com/xamarin/Xamarin.Forms/issues/5428
and https://github.com/xamarin/Xamarin.Forms/pull/10500
Other thread missing IsVisible option https://github.com/xamarin/Xamarin.Forms/issues/5232
IsVisible was planned but removed because of naming issues
https://github.com/xamarin/Xamarin.Forms/pull/9023
UPDATE 2!
TODAYs Update/Release from Xamarin.Forms 4.5.0.657 to 4.6.0.726 solved the issue. Adding and removing is no working fine in iOS!
https://github.com/xamarin/Xamarin.Forms/pull/10500
Xamarin.Forms 4.6 Branch: Latest commit 18 hours ago
You could remain only first contentpage inside Tab in AppShell .
<TabBar x:Name="RootTab">
<Tab Title="Tab1">
<ShellContent
Route="page1"
Title="page1"
ContentTemplate="{DataTemplate view:Page1}" />
</Tab>
<Tab
Title="Tab2" >
<ShellContent
Route="tab2"
Title="tab2"
ContentTemplate="{DataTemplate view:Tab2Page}" />
</Tab>
<Tab
Title="Tab3" >
<ShellContent
Route="tab3"
Title="tab3"
ContentTemplate="{DataTemplate view:Tab3Page}" />
</Tab>
</TabBar>
And navigate between pages using old ways
// your "wizard"
await Navigation.PushAsync(new Page2());
Update
If you want hide the back button , add a transparent image into project ,and set in xaml
<Shell.BackButtonBehavior>
<BackButtonBehavior IconOverride="transparent.png" IsEnabled="False"/>
</Shell.BackButtonBehavior>
Upgrading to Xamarin 4.6 fixed the bug / problem.
Here is my code / solution.
AppShell.xaml
<TabBar Route="tabBar">
<Tab
x:Name="myTab"
Route="tab1"
Icon="tab_icon1.png">
<ShellContent
x:Name="shellStart"
Route="route1A"
Title="title"
ContentTemplate="{DataTemplate view:Page1A}" />
</Tab>
<Tab
Route="tab2"
Icon="tab_icon2.png">
<ShellContent
Route="route2"
Title="title2"
ContentTemplate="{DataTemplate view:Page2}" />
</Tab>
</Tab>
<Tab
Route="tab3"
Icon="tab_icon3.png">
<ShellContent
Route="route3"
Title="title3"
ContentTemplate="{DataTemplate view:Page3}" />
</Tab>
</TabBar>
AppShell.xaml.cs
public ShellContent shell0;
public ShellContent shell1;
public ShellContent shell2;
public ShellContent shell3;
public static Tab tabLocal;
constructor
tabLocal = myTab;
shell0 = shellStart;
shell1 = new ShellContent()
{
Content = new Page1B(),
Title = "",
Route = ""
};
shell2 = .... Page1C() ...
shell3 = .... Page1D() ...
...
Switching page 0 to 1
AppShell.tabLocal.Items.Add(shell1);
AppShell.tabLocal.Items.Remove(shell0);
Maybe these two method for handling the navigation is useful
protected async override void OnNavigating(ShellNavigatingEventArgs args)
protected override void OnNavigated(ShellNavigatedEventArgs args)
I try to implement shell page nevertheless when trying to compile i get following error in MasterDetailShell.xaml. I assume something is wrong within the lines regardless path.
ContentTemplate="{DataTemplate local:Page1}"
Error:
Type Page1 not found in xmlns MobileAppXamarinForms
This is my code:
App.cs:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new MasterDetailShell();
}
}
MasterDetailShell.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MasterDetailShell : Shell
{
public MasterDetailShell()
{
InitializeComponent();
}
}
MasterDetailShell.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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="MobileAppXamarinForms.Views.MasterDetailShell.MasterDetailShell">
<FlyoutItem Title="MyTabbApp"
Shell.TabBarIsVisible="False"
FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Title="Bears" Icon="" IsTabStop="True" ContentTemplate="{DataTemplate local:Page1}"></ShellContent>
<ShellContent Title="Bears" Icon="" IsTabStop="True" ContentTemplate="{DataTemplate local:Page2}"></ShellContent>
</FlyoutItem>
<ShellContent Title="About" Icon="" ContentTemplate="{DataTemplate local:Page1}"></ShellContent>
</Shell>
Files location:
you are using the local namespace without ever declaring it
xmlns:local="using:ThisIsTheNamespaceForPage1"
to determine which namespace to use, open Page.xaml.cs and look at its namespace declaration
I had the same problem but it has been fixed just correct the namespace of an necessary class or add an necessary class
xmlns:local="clr-namespace:DiplayAnimalCollection"
Using correct place
xmlns:local="clr-namespace:DiplayAnimalCollection.Views"