Xamarin XAML: calling a Shell page with a parameter - xaml

Suppose you have the following AppShell.xaml:
<TabBar>
<ShellContent Title="Page1" ContentTemplate="{DataTemplate local:Page1}" />
<ShellContent Title="Page2" ContentTemplate="{DataTemplate local:Page2}">
</TabBar>
Also suppose Page2 is identical to Page1 except for one property, which can be easily parameterized.
So I'd like to be able to do this:
<TabBar>
<ShellContent Title="Page1" ContentTemplate="{DataTemplate local:Page1}" />
<ShellContent Title="Page2" ContentTemplate="{DataTemplate local:Page1}"
ContentTemplateParameter="somevalue">
</TabBar>
Problem is, there is no such thing as ContentTemplateParameter. So is there a way to achieve this functionality? The critical part here is that I need to call it from an App-level Tab bar, not from one page to another.
P.S. See my solution below.

Answering my own question; I have come up with a solution.
Assign one of the links a route name:
<TabBar>
<ShellContent Title="Page1" ContentTemplate="{DataTemplate local:Page1}" />
<ShellContent Title="Page2" ContentTemplate="{DataTemplate local:Page1}"
Route ="somevalue">
</TabBar>
Then in Page1's constructor you can check whether that name was in the route:
if(Shell.Current.CurrentItem.CurrentItem.Route.Contains("somevalue")) {
// do something
} else {
// do something else
}

Related

MAUI flyout is duplicating as buttons at the bottom of the screen

I'm developing my first MAUI app. I've googled this, and cannot find out how to get rid of it.
I have two Tabs defined in my AppShell Flyout. They show up in the flyout itself fine, and work beautifully, just as expected. But then they ALSO duplicate as buttons at the bottom of the screen, pointed to by the blue arrows in the screenshot below.
Here's the full XAML for my AppShell:
<Shell
x:Class="OurApp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:OurApp"
Shell.FlyoutBehavior="Flyout" Shell.NavBarIsVisible="False">
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<Tab Title="Application" Route="application">
<ShellContent Title="Login" Route="login" ContentTemplate="{DataTemplate local:Login}" />
<ShellContent Title="About" Route="about" ContentTemplate="{DataTemplate local:About}" />
<ShellContent Title="Exit" Route="exit" ContentTemplate="{DataTemplate local:Exit}" />
</Tab>
<Tab x:Name="ModulesTab" Title="Modules" Route="modules">
<ShellContent Title="Receiving" Route="receiving" ContentTemplate="{DataTemplate local:Receiving}" />
<ShellContent Title="Shipping" Route="shipping" ContentTemplate="{DataTemplate local:Shipping}" />
<ShellContent Title="Putaway" Route="putaway" ContentTemplate="{DataTemplate local:Putaway}" />
</Tab>
</FlyoutItem>
</Shell>
How do I hide those buttons at the bottom, while keeping the actual Flyout visible?
I tried doing this in my XAML:
<Shell ... Shell.NavBarIsVisible="False">
But that hides both the buttons AND the flyout! I want to get rid of the buttons but keep the flyout. I don't need it duplicated like that.
Or if there's a way to hide the flyout but keep the buttons, that would work too, though I'd prefer keeping the flyout. Ultimately, I just want to eliminate the duplication.
You could try using TabBarIsVisible property of shell:
<Shell
x:Class="GoodSam.MATTRAK.AppShell"
....
Shell.TabBarIsVisible="False">
(you can also add Shell.TabBarIsVisible="False" to the shell content).
For more info, you could refer to TabBar and Tab visibility
Hope it works for you.
The suggestion in comments by #ToolmakerSteve worked. I thought the FlyoutItem element was a root, and could only occur once. However breaking the tabs out into separate FlyoutItems solved it.
Updated the flyouts to be defined as so:
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<Tab Title="Application" Route="application">
<ShellContent Title="Login" Route="login" ContentTemplate="{DataTemplate pages:LoginPage}" />
<ShellContent Title="About" Route="about" ContentTemplate="{DataTemplate pages:AboutPage}" />
<ShellContent Title="Exit" Route="exit" ContentTemplate="{DataTemplate pages:ExitPage}" />
</Tab>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems" >
<Tab x:Name="ModulesTab" Title="Modules" Route="modules" IsVisible="False">
<ShellContent Title="Receiving" Route="receiving" ContentTemplate="{DataTemplate pages:InventoryReceivingPage}" />
<ShellContent Title="Physical" Route="physical" ContentTemplate="{DataTemplate pages:InventoryPhysicalPage}" />
</Tab>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems" >
<Tab x:Name="DataTab" Title="Data" Route="data" IsVisible="False">
<ShellContent Title="Drop Downs" Route="dropdowns" ContentTemplate="{DataTemplate pages:DropdownsDataPage}" />
</Tab>
</FlyoutItem>
Which then gave me the separate tabs (Log Out is a MenuItem under the flyoutitems)...
without any extraneous buttons at the bottom of the screen...

How to get the default shell flyout icon to react when android dark theme is switched on/off

I have an app which uses the shell flyout. When I added the flyout, it automatically created an icon as shown in the image below:
However, when I switch the android dark theme off:
The flyout icon remains white making it difficult to see:
I am using AppThemeBinding to automatically theme the app accordingly based on the system theme selected by the user, but I do not know how to change the flyout icon to a darker color if the user switches off the dark theme from the android settings.
Any idea how to do that?
The AppShell.xaml currently looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MAUIApp1.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MAUIApp1"
FlyoutBackgroundColor="{AppThemeBinding Light=#f2f2f2, Dark=#2a2a2a}">
<Shell.Resources>
<ResourceDictionary>
...
</ResourceDictionary>
</Shell.Resources>
<Shell.FlyoutHeader>
...
</Shell.FlyoutHeader>
<Shell.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</Shell.ItemTemplate>
<FlyoutItem Title="Item1" Icon="item1.svg">
<ShellContent ContentTemplate="{DataTemplate local:page1}" Route="page1"/>
</FlyoutItem>
<FlyoutItem Title="Item2" Icon="item2.svg">
<ShellContent ContentTemplate="{DataTemplate local:page2}" Route="page2"/>
</FlyoutItem>
<FlyoutItem Title="Item3" Icon="item3.svg">
<ShellContent ContentTemplate="{DataTemplate local:page3}" Route="page3"/>
</FlyoutItem>
<Shell.FlyoutFooter>
...
</Shell.FlyoutFooter>
</Shell>
Generally, you could override the Foreground color of the Shell to accomplish this:
<Shell
x:Class="MAUIApp1.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MAUIApp1"
FlyoutBackgroundColor="{AppThemeBinding Light=#f2f2f2, Dark=#2a2a2a}"
Shell.ForegroundColor="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}">
Alternatively, you can overwrite the style directly, by editing the Resources\Styles\styles.xaml:
<Style TargetType="Shell" ApplyToDerivedTypes="True">
<Setter Property="Shell.BackgroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource Gray950}}" />
<!--<Setter Property="Shell.ForegroundColor" Value="{OnPlatform WinUI={StaticResource Primary}, Default={StaticResource White}}" />-->
<Setter Property="Shell.ForegroundColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
</Style>

TargetType ShellContent style Maui

I would like to apply a common style for each ShellContent element in my app.xaml.
My problem is that I don't see any ShellContent property in my TargetType
AppShell.xaml
<ShellContent Title="TITLE1"
ContentTemplate="{DataTemplate local:Page1}"
Route="Route1"
Icon="Icon1" />
<ShellContent Title="TITLE2"
ContentTemplate="{DataTemplate local:Page2}"
Route="Route2"
Icon="Icon2" />
I would like something in this style in my App.xaml
<Style TargetType="ShellContent">
<Setter Property="Title" Value="{StaticResource Black}" />
</Style>
In Styles.xaml, which is merged into App.xaml, find and change the styles applied to Shell:
<Style TargetType="Shell" ApplyToDerivedTypes="True">
<Setter Property="Shell.TitleColor" Value="HotPink" />
<!--TBD_WHAT_PROPERTY?? <Setter Property="Shell.FontFamily" Value="..." /> --/>
</Style>
This will change the color of Titles of ShellContents, on tabbar (On Android, but not on Windows - bug?), and on each page.
Unfortunately, I have not found any way to change the properties of the flyout.
Unfortunately, I have not found any way to change the font used.

MotionLayout how rotate element?

Now I have a motion with two elements. When first is 50% duration then second starts. But I want to rotate second element in half transition to the end. I tryed to do this in KeyCycle but it Doesnt work. Maybe I need to do this in KeyAttribute? But it doesn't work too. Maybe someone give me a tip?
Scene:
<Transition
motion:autoTransition="animateToEnd"
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#id/start"
motion:duration="1500">
<KeyFrameSet>
<KeyPosition
motion:framePosition="50"
motion:keyPositionType="pathRelative"
motion:motionTarget="#id/imageView"
motion:percentX="1" />
<KeyPosition
motion:framePosition="50"
motion:keyPositionType="pathRelative"
motion:motionTarget="#id/cardYes"
motion:percentX="0" />
<KeyCycle
android:translationY="50dp"
motion:framePosition="300"
motion:motionTarget="#+id/imageView"
motion:waveOffset="50dp"
motion:wavePeriod="2"
motion:waveShape="sin" />
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/imageView"
android:layout_width="0dp"
android:layout_height="10dp"
android:layout_marginTop="15dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintRight_toRightOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/cardYes"
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintRight_toLeftOf="parent"
motion:layout_constraintTop_toBottomOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/imageView"
android:layout_width="400dp"
android:layout_height="290dp"
android:layout_marginTop="15dp"
motion:layout_constraintRight_toRightOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/cardYes"
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toBottomOf="#+id/imageView" />
</ConstraintSet>
must have 3 KeyCycle can work well.
In your case, maybe you need code like this:
<KeyFrameSet>
<KeyAttribute
android:rotation="0"
motion:framePosition="50"
motion:motionTarget="#id/view"
/>
<KeyAttribute
android:rotation="360"
motion:framePosition="100"
motion:motionTarget="#id/view"
/>
</KeyFrameSet>

How to set shell upper tabs to take full width

I'm using Xamarin.forms 5.0 and Shell.
My XAML code is
<TabBar Route="Root">
<Tab x:Name="NewsListPageTab" Title="News" Route="NewsListPage">
<Tab.Icon>
<FontImageSource FontFamily="{StaticResource FaRegular}" Glyph="{x:Static utils:FontAwesomeIcons.Newspaper}" />
</Tab.Icon>
<ShellContent ContentTemplate="{DataTemplate pages:NewsListPage}" Title="News1">
<ShellContent.Icon>
<FontImageSource
FontFamily="{StaticResource FaRegular}"
Glyph="{x:Static utils:FontAwesomeIcons.BadgePercent}">
</FontImageSource>
</ShellContent.Icon>
</ShellContent>
<ShellContent ContentTemplate="{DataTemplate pages:NewsListPage}" Title="News2">
<ShellContent.Icon>
<FontImageSource
FontFamily="{StaticResource FaRegular}"
Glyph="{x:Static utils:FontAwesomeIcons.BadgePercent}">
</FontImageSource>
</ShellContent.Icon>
</ShellContent>
</Tab>
</TabBar>
The overall appearance that I'm trying to create is like this image.
How is it possible to add icons to the inner tabs and make them full width in the app shell, please?
I found an easy solution: instead of using ShellContent for upper tabs, we can use TabbedPages with pages representing the tabs we need.
<Tab Title="ُShop" Route="CompaniesTabs">
<ShellContent ContentTemplate="{DataTemplate retailer:CompaniesTabs}" />
</Tab>
The TabbedPage code is as followed:
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Retailer.CompaniesTabs">
<retailer:CompaniesStatusPage Title="Store1" />
<retailer:CompaniesListPage Title="Store3" />
<retailer:CompaniesFavoritePage Title="Store3" />
</TabbedPage>
That's it.