How can I bind this Icon's Color to this Label Color? - xaml

As you can see below, the FlyoutItem has an Icon and a Title.
<FlyoutItem Title="About" >
<FlyoutItem.Icon>
<FontImageSource FontFamily="MaterialDesignIconFont"
Glyph="{StaticResource InformationOutlineGlyph}"
Color="Green" />
</FlyoutItem.Icon>
<ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
</FlyoutItem>
The Title Color changes automatically because of this Style:
<Style Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor" Value="LightBlue"></Setter>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="White" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource PrimaryColor}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource PrimaryColor}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
So the Label that is the Title changes color automatically when the FlyoutItem is selected. I need the Icon to do the same thing. I could use a trigger to set the FontImageSource but that comes with its own problems.
Given the TargetName "FlyoutItemLabel" from the above Style, is it possible to create a binding from the FontImageSource.Color to each FlyoutItem's "FlyoutItemLabel".Color? It would have to bind upward to the FlyoutItem ancestor, then downward to the <Label x:Name="FlyoutItemLabel" />, wouldn't it?

You could set the [ItemTemplate][1] of FlyoutItem as you want
<Shell.ItemTemplate>
<DataTemplate >
<Grid Style="{StaticResource FloutItemStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding xxx}"
Margin="5"
BackgroundColor="{Binding Source={x:Reference label} ,Path=BackgroundColor}"
HeightRequest="45" />
<Label Grid.Column="1"
x:Name="label"
BackgroundColor="Red"
Text="{Binding Title}"
FontAttributes="Italic"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>

Related

Issues with styling a radio button in .Net MAUI

I am running into some issues with styling a radio button in .Net MAUI. Initially, I noticed the the radio button look-and-feel is not consistent across Windows and Android, as can be seen in the image below:
Not only are they different, but the available options for styling the button are limited. The only options for defining colors are "BorderColor", "BackgroundColor", and "TextColor". Both "BorderColor" and "BackgroundColor" have absolutely no effect on the color of the radio button itself. I'd like to change the color of the actual radio button.
So I decided to create a control template to help me out. Here is my control template:
<ControlTemplate x:Key="RadioButtonTemplate">
<Border Stroke="Transparent" BackgroundColor="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CheckedStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter TargetName="check" Property="Opacity" Value="1" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked">
<VisualState.Setters>
<Setter TargetName="check" Property="Opacity" Value="0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid WidthRequest="20" HeightRequest="20" Grid.Column="0" VerticalOptions="Center" HorizontalOptions="Center">
<Ellipse x:Name="border_circle" StrokeThickness="2" Stroke="DarkBlue" Fill="White" WidthRequest="18" HeightRequest="18" HorizontalOptions="Center" VerticalOptions="Center" />
<Ellipse x:Name="check" Fill="DarkBlue" WidthRequest="10" HeightRequest="10" HorizontalOptions="Center" VerticalOptions="Center" />
</Grid>
<ContentPresenter Margin="10,0,0,0" Grid.Column="1" HorizontalOptions="Start" VerticalOptions="Center" />
</Grid>
</Border>
</ControlTemplate>
<Style TargetType="RadioButton" x:Key="RadioButtonStyle">
<Setter Property="ControlTemplate" Value="{StaticResource RadioButtonTemplate}" />
</Style>
This worked reasonably well, so now I get the following look-and-feel on both Android and Windows:
Now I have one last problem. When I was using the default radio buttons (without my control template), they would reliably turn a "light gray" color whenever I set IsEnabled to false. I'd like to make it so that I can disable my radio button and have it turn a light gray color (to indicate that it is disabled) while still using my control template so I have a unified look-and-feel.
So I attempted to add a Disabled visual state to my control template, but it doesn't seem to be working. Here is my new control template with a Disabled state:
<ControlTemplate x:Key="RadioButtonTemplate">
<Border Stroke="Transparent" BackgroundColor="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CheckedStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter TargetName="check" Property="Opacity" Value="1" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked">
<VisualState.Setters>
<Setter TargetName="check" Property="Opacity" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter TargetName="border_circle" Property="Stroke" Value="LightGray" />
<Setter TargetName="check" Property="Fill" Value="LightGray" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid WidthRequest="20" HeightRequest="20" Grid.Column="0" VerticalOptions="Center" HorizontalOptions="Center">
<Ellipse x:Name="border_circle" StrokeThickness="2" Stroke="DarkBlue" Fill="White" WidthRequest="18" HeightRequest="18" HorizontalOptions="Center" VerticalOptions="Center" />
<Ellipse x:Name="check" Fill="DarkBlue" WidthRequest="10" HeightRequest="10" HorizontalOptions="Center" VerticalOptions="Center" />
</Grid>
<ContentPresenter Margin="10,0,0,0" Grid.Column="1" HorizontalOptions="Start" VerticalOptions="Center" />
</Grid>
</Border>
</ControlTemplate>
<Style TargetType="RadioButton" x:Key="RadioButtonStyle">
<Setter Property="ControlTemplate" Value="{StaticResource RadioButtonTemplate}" />
</Style>
Unfortunately, it's not working. Not only does the color not change when the radio button is disabled, but also my 2nd setter (setting the "Fill" property of the "check" object) causes a compile-time error as well ("Cannot resolve property Fill on type Border").
Any suggestions?
I was able to figure out a way to do what I needed to do. Rather than use the "Disabled" visual state in the visual state group, I was able to use style triggers. So now my control template and its corresponding style look like this:
<ControlTemplate x:Key="RadioButtonTemplate">
<Border Stroke="Transparent" BackgroundColor="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CheckedStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter TargetName="check" Property="Opacity" Value="1" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked">
<VisualState.Setters>
<Setter TargetName="check" Property="Opacity" Value="0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid WidthRequest="20" HeightRequest="20" Grid.Column="0" VerticalOptions="Center" HorizontalOptions="Center">
<Ellipse x:Name="border_circle" StrokeThickness="2" Stroke="{TemplateBinding BorderColor}" Fill="White" WidthRequest="18" HeightRequest="18" HorizontalOptions="Center" VerticalOptions="Center" />
<Ellipse x:Name="check" Fill="{TemplateBinding BorderColor}" WidthRequest="10" HeightRequest="10" HorizontalOptions="Center" VerticalOptions="Center" />
</Grid>
<ContentPresenter Margin="10,0,0,0" Grid.Column="1" HorizontalOptions="Start" VerticalOptions="Center" />
</Grid>
</Border>
</ControlTemplate>
<Style TargetType="RadioButton" x:Key="RadioButtonStyle">
<Setter Property="ControlTemplate" Value="{StaticResource RadioButtonTemplate}" />
<Style.Triggers>
<Trigger TargetType="RadioButton" Property="IsEnabled" Value="False">
<Setter Property="BorderColor" Value="LightGray" />
</Trigger>
<Trigger TargetType="RadioButton" Property="IsEnabled" Value="True">
<Setter Property="BorderColor" Value="DarkBlue" />
</Trigger>
</Style.Triggers>
</Style>

How to change the color of the selected item in flyout menu?

I have set a background color and text color and some other color properties like disable and unselected colors, but none seem to change the selected item background color.
Which if the properties below will I have to change to make it look the way I want? Or else what do I need to add on my code?
I have the following:
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
Title="Example"
x:Class="TrackBus.AppShell"
FlyoutHeaderBehavior="CollapseOnScroll"
FlyoutBackgroundColor="{StaticResource Primary}">
<Shell.Resources>
<ResourceDictionary>
<Style x:Key="BaseStyle" TargetType="Element">
<Setter Property="Shell.BackgroundColor" Value="{StaticResource Primary}" />
<Setter Property="Shell.ForegroundColor" Value="White" />
<!--Foreground is the menu icon color-->
<Setter Property="Shell.TitleColor" Value="White" />
<Setter Property="Shell.DisabledColor" Value="Magenta" />
<Setter Property="Shell.UnselectedColor" Value="Cyan" />
</Style>
<Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}" />
<Style Class="FlyoutItemLabelStyle" TargetType="Label">
<Setter Property="TextColor" Value="Cyan"></Setter>
</Style>
<Style Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor" Value="Magenta"></Setter>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource Secondary}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Blue"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource SecondaryLight}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style Class="MenuItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource SecondaryLight}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ResourceDictionary>
</Shell.Resources>
<Shell.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="60,Auto">
<Image Source="{Binding FlyoutIcon}"
Margin="5"
HeightRequest="35" />
<Label Grid.Column="1"
Text="{Binding Title}"
VerticalTextAlignment="Center"
FontSize="Title"
TextColor="{StaticResource SecondaryLight}" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
<Shell.MenuItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="60,Auto">
<Image Source="{Binding Icon}"
Margin="5"
HeightRequest="35" />
<Label Grid.Column="1"
Text="{Binding Text}"
VerticalTextAlignment="Center"
FontSize="Title"
TextColor="{StaticResource SecondaryLight}"/>
</Grid>
</DataTemplate>
</Shell.MenuItemTemplate>
Primary is dark blue and
SecondaryLight is yellow
Currently I have this:
I want it to look like this:
We need to override the FlyoutItemLayoutStyle ,MenuItemLayoutStyle and modify the value in CommonStates and Selected .
<Style Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Orange" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Orange" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Black" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<!--
Custom Style you can apply to any Flyout Item
-->
<Style Class="MenuItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Orange" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Orange" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Black" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
What worked for me was to make a custom FloutItemStyle template, just as you did inside your ResourceDictionary, like this:
<Style x:Key="FloutItemStyle" TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Orange"/>
<Setter TargetName="_label" Property="Label.TextColor" Value="Black" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
Then, with that template, I changed the flyout item appearance similar to what we can find in the official documentation:
<Shell.ItemTemplate>
<DataTemplate>
<Grid Style="{StaticResource FloutItemStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<Image Source="{Binding FlyoutIcon}"
Margin="10"
HeightRequest="50"
HorizontalOptions="EndAndExpand" />
<Label Grid.Column="1"
Text="{Binding Title}"
TextColor="{StaticResource LightTextColor}"
FontSize="Body"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Start"
x:Name="_label">
</Label>
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
But the most critical part is to assign a name to the Label with the x:Name="_label" property to be able to find it with the selected target item (TargetName="_label").
Finally I just added my menu item (Even with some FontAwesome icons in my case):
<FlyoutItem Title="MyMenuItem">
<FlyoutItem.Icon>
<FontImageSource
FontFamily="{StaticResource FontAwesomeSolid}"
Size="Large"
Glyph="{x:Static fontawesome:FontAwesomeIcons.User}"
Color="{StaticResource LightTextColor}">
</FontImageSource>
</FlyoutItem.Icon>
<ShellContent ContentTemplate="{DataTemplate local:Index}" />
</FlyoutItem>
Hope this answer helps anyone trying to customize every part of their menus, including label colors.

What am I missing about my color configurations in my Xamarin Forms App.Shell?

Early today I've asked for help here because my Xamarin App wasn't working like I expected.
After the help about how to change my Action Bar color, I start wondering "why the way it says on tutorials I've found does not work"
EDIT
<?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:Mobile.XamarinApp.Views"
xmlns:sys="clr-namespace:System;assembly=netstandard"
x:Class="Mobile.XamarinApp.AppShell"
BackgroundColor="{StaticResource Primary}"
Shell.ForegroundColor="{StaticResource Background}"
Shell.TitleColor="{StaticResource Background}">
<!--
The overall app visual hierarchy is defined here, along with navigation.
https://learn.microsoft.com/xamarin/xamarin-forms/app-fundamentals/shell/
-->
<Shell.Resources>
<ResourceDictionary>
<Style x:Key="BaseStyle" TargetType="Element" ApplyToDerivedTypes="True">
<Setter Property="Shell.Title" Value="App" />
<Setter Property="Shell.BackgroundColor" Value="{StaticResource Background}" />
<Setter Property="Shell.ForegroundColor" Value="{StaticResource Primary}" />
<Setter Property="Shell.TitleColor" Value="{StaticResource Primary}" />
<Setter Property="Shell.DisabledColor" Value="HotPink" />
<Setter Property="Shell.UnselectedColor" Value="{StaticResource Secondary}" />
<Setter Property="Shell.TabBarBackgroundColor" Value="Red" />
<Setter Property="Shell.TabBarForegroundColor" Value="Blue"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="Green"/>
<Setter Property="Shell.TabBarTitleColor" Value="Yellow"/>
<Setter Property="Shell.FlyoutHeight" Value="400"/>
<Setter Property="Shell.FlyoutWidth" Value="200"/>
</Style>
<Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
<Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}" />
<!--
Default Styles for all Flyout Items
https://learn.microsoft.com/xamarin/xamarin-forms/app-fundamentals/shell/flyout#flyoutitem-and-menuitem-style-classes
-->
<Style Class="teste" TargetType="TabbedPage">
<Setter Property="BackgroundColor" Value="Red"/>
</Style>
<Style Class="FlyoutItemLabelStyle" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource Accent}"></Setter>
</Style>
<Style Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor" Value="{StaticResource Primary}"></Setter>
<Setter Property="HeightRequest" Value="50" />
<Setter Property="HorizontalOptions" Value="Start"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource Primary}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource Secondary}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<!--
Custom Style you can apply to any Menu Item
-->
<Style Class="MenuItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Accent}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ResourceDictionary>
</Shell.Resources>
<Shell.FlyoutHeaderTemplate>
<DataTemplate>
<Grid BackgroundColor="{StaticResource Secondary}" HeightRequest="56" Padding="10,0,10,0">
<Label Text="Menu"
TextColor="{StaticResource Primary}"
FontAttributes="Bold"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Start"/>
</Grid>
</DataTemplate>
</Shell.FlyoutHeaderTemplate>
<Shell.FlyoutFooterTemplate>
<DataTemplate>
<StackLayout>
<Label Text="Xaminals"
TextColor="Black"
FontAttributes="Bold"
HorizontalOptions="Center" />
<Label Text="{Binding Source={x:Static sys:DateTime.Now}, StringFormat='{0:MMMM dd, yyyy}'}"
TextColor="Black"
HorizontalOptions="Center" />
</StackLayout>
</DataTemplate>
</Shell.FlyoutFooterTemplate>
<!-- Splash Screen/Start Page -->
<!--<ShellItem Route="loading">
<ShellContent ContentTemplate="{DataTemplate local:LoadingPage}" />
</ShellItem>-->
<!-- SignIn Page -->
<ShellContent Route="SignInPage" ContentTemplate="{DataTemplate local:SignInPage}"/>
<!--
When the Flyout is visible this defines the content to display in the flyout.
FlyoutDisplayOptions="AsMultipleItems" will create a separate flyout item for each child element
https://learn.microsoft.com/dotnet/api/xamarin.forms.shellgroupitem.flyoutdisplayoptions?view=xamarin-forms
-->
<FlyoutItem Title="Browse">
<ShellContent Route="ItemsPage" ContentTemplate="{DataTemplate local:ItemsPage}" />
</FlyoutItem>
<FlyoutItem Title="About">
<ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
</FlyoutItem>
<FlyoutItem Title="Cadastro">
<ShellContent Route="ItemsPage" ContentTemplate="{DataTemplate local:ItemsPage}" />
</FlyoutItem>
<!-- When the Flyout is visible this will be a menu item you can tie a click behavior to -->
<MenuItem Text="Sair" StyleClass="MenuItemLayoutStyle" Clicked="OnSignOutMenuItemClicked">
</MenuItem>
<!--
TabBar lets you define content that won't show up in a flyout menu. When this content is active
the flyout menu won't be available. This is useful for creating areas of the application where
you don't want users to be able to navigate away from. If you would like to navigate to this
content you can do so by calling
await Shell.Current.GoToAsync("//LoginPage");
-->
<!-- Optional Templates
// These may be provided inline as below or as separate classes.
// This header appears at the top of the Flyout.
// https://learn.microsoft.com/xamarin/xamarin-forms/app-fundamentals/shell/flyout#flyout-header
<Shell.FlyoutHeaderTemplate>
<DataTemplate>
<Grid>ContentHere</Grid>
</DataTemplate>
</Shell.FlyoutHeaderTemplate>
// ItemTemplate is for ShellItems as displayed in a Flyout
// https://learn.microsoft.com/xamarin/xamarin-forms/app-fundamentals/shell/flyout#define-flyoutitem-appearance
-->
<!--<Shell.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Text="{Binding Title}"
FontAttributes="Italic"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>-->
<!--
// MenuItemTemplate is for MenuItems as displayed in a Flyout
// https://learn.microsoft.com/xamarin/xamarin-forms/app-fundamentals/shell/flyout#define-menuitem-appearance
-->
<!--<Shell.MenuItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Text="{Binding Text}"
FontAttributes="Italic"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
</Shell.MenuItemTemplate>-->
While I stand for the configuration of Shell on those 3 lines, it does not work.
<Setter Property="Shell.BackgroundColor" Value="{StaticResource Background}" />
<Setter Property="Shell.ForegroundColor" Value="{StaticResource Primary}" />
<Setter Property="Shell.TitleColor" Value="{StaticResource Primary}" />
After getting help, the 3 last lines shell config at the header, made it work.
BackgroundColor="{StaticResource Primary}"
Shell.ForegroundColor="{StaticResource Background}"
Shell.TitleColor="{StaticResource Background}"
The question is, am I doing something wrong? Did I miss something?
I just want to change the color of my Tabbar, action bar and etc from my Shell.Resources Dictionary like the tutorials shows us to do.
thanks in advance
You probably have to Target ShellContent type also:
<Style TargetType="ShellContent" BasedOn="{StaticResource BaseStyle}"/>

Xamarin Forms: How Can I Change the FlyoutItem.Icon's Color When It Is Selected/Deselected?

I am using Material Design Font Icons as my icon source for my project. The trouble is, since it's a font it needs a different color when selected vs. when deselected (as shown - the deselected white ones have white icons, which isn't awesome).
How can I modify the Style to change the color of the icon like it does the text and background color?
<!-- redacted because it would've never worked -->
Edit 1:
Consensus is that using the VSM isn't going to work because it doesn't derive from VisualElement. I've gotten it to work using a Trigger - but I'm not happy with the implementation. This works:
<Shell.Resources>
<ResourceDictionary>
<Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}">
<Style.Triggers>
<Trigger TargetType="FlyoutItem" Property="IsChecked" Value="True">
<Setter Property="Title" Value="Checked" />
<Setter Property="FlyoutIcon" >
<Setter.Value>
<FontImageSource FontFamily="MaterialDesignIconFont"
Glyph="{StaticResource InformationOutlineGlyph}"
Color="White" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</Shell.Resources>
<FlyoutItem Title="About" >
<FlyoutItem.Icon>
<FontImageSource FontFamily="MaterialDesignIconFont"
Glyph="{StaticResource InformationOutlineGlyph}"
Color="Green" />
</FlyoutItem.Icon>
<ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
</FlyoutItem>
... but as you can see, I have to set the entire FontImageSource value - which has the Glyph property - so I have to repeat this Style each time for each FlyoutItem.
How can I rewrite this Style to be reusable and only change the color, not the other properties?
I had the same question and solved it as follows
Create a custom flyout with an additional IconGlyphProperty
class FlyoutItemIconFont : FlyoutItem
{
public static readonly BindableProperty IconGlyphProperty = BindableProperty.Create(nameof(IconGlyphProperty), typeof(string), typeof(FlyoutItemIconFont), string.Empty);
public string IconGlyph
{
get { return (string)GetValue(IconGlyphProperty); }
set { SetValue(IconGlyphProperty, value); }
}
}
Create a FlyoutItemTemplate with two Lables and VisualStateManager
<Shell.ItemTemplate>
<DataTemplate>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="White" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Primary}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Label x:Name="FlyoutItemIcon"
FontFamily="MaterialDesignFont"
Text="{Binding IconGlyph}"
TextColor="{Binding Source={x:Reference FlyoutItemLabel} ,Path=TextColor}"
FontSize="30"
Margin="5"/>
<Label x:Name="FlyoutItemLabel"
Grid.Column="1"
Text="{Binding Title}"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
Replace the original FlyoutItem in AppShell.xaml with the custom FlyoutItem
<controls:FlyoutItemIconFont Title="About" IconGlyph="{StaticResource IconInfo}">
<ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
</controls:FlyoutItemIconFont>
<controls:FlyoutItemIconFont Title="Browse" IconGlyph="{StaticResource IconListBulleted}">
<ShellContent Route="ItemsPage" ContentTemplate="{DataTemplate local:ItemsPage}" />
</controls:FlyoutItemIconFont>
Add the BaseStyle to the customFlyouItem
<Shell.Resources>
<ResourceDictionary>
<x:String x:Key="IconInfo">󰋽</x:String>
<x:String x:Key="IconListBulleted">󰉹</x:String>
...
<Style TargetType="controls:FlyoutItemIconFont" BasedOn="{StaticResource BaseStyle}"/>
</ResourceDictionary>
</Shell.Resources>
Here is the Result
Create the Material Design Icons.
<Application.Resources>
<ResourceDictionary>
<Color x:Key="fgColor">#66169C</Color>
<Color x:Key="bgColor">#FFFFFF</Color>
<Color x:Key="OverDueItem">#FF1C07</Color>
<OnPlatform x:Key="Material" x:TypeArguments="x:String">
<On Platform="iOS" Value="Material Design Icons" />
<On Platform="Android" Value="materialdesignicons-webfont.ttf#Material Design Icons" />
</OnPlatform>
<Style x:Key="MaterialIcons" TargetType="{x:Type Label}">
<Setter Property="FontFamily" Value="{DynamicResource Material}" />
<Setter Property="FontSize" Value="100" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="Center" />
<Setter Property="TextColor" Value="{DynamicResource fgColor}" />
<Setter Property="FontSize" Value="Large" />
</Style>
</ResourceDictionary>
</Application.Resources>
For more details about the Material Design Icons, you could download from the GitHub. https://github.com/WendyZang/Test/tree/master/MaterialDesignIcons/App2
And then create the style to change the background color when you selected.
<Style x:Key="FloutItemStyle" TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Accent" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
Change the Label TextColor with the Triggers.
<Shell.ItemTemplate>
<DataTemplate>
<Grid x:Name="grid" Style="{StaticResource FloutItemStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Label Style="{StaticResource MaterialIcons}" Text="">
<Label.Triggers>
<DataTrigger
Binding="{Binding Source={x:Reference grid}, Path=BackgroundColor}"
TargetType="Label"
Value="Accent">
<Setter Property="TextColor" Value="White" />
</DataTrigger>
</Label.Triggers>
</Label>
<Label
Grid.Column="1"
FontAttributes="Italic"
Text="{Binding Title}"
VerticalTextAlignment="Center">
<Label.Triggers>
<DataTrigger
Binding="{Binding Source={x:Reference grid}, Path=BackgroundColor}"
TargetType="Label"
Value="Accent">
<Setter Property="TextColor" Value="White" />
</DataTrigger>
</Label.Triggers>
</Label>
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
Screenshot:
Updated:
Change:
<Setter Property="TextColor" Value="White" />
To:
<Setter Property="BackgroundColor" Value="Yellow" />
The whold trigger of the shell itemtemplate.
<Label.Triggers>
<DataTrigger
Binding="{Binding Source={x:Reference grid}, Path=BackgroundColor}"
TargetType="Label"
Value="Accent">
<!--<Setter Property="TextColor" Value="White" />-->
<Setter Property="BackgroundColor" Value="Yellow" />
</DataTrigger>
</Label.Triggers>
Screenshot:

Rounded corner for ToggleButton in UWP

<Style x:Key="tests" TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ToggleButton
Background="{Binding Background,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}"
IsChecked="{Binding IsChecked,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}"
Content="{Binding Content,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I am using above code to customize toggle button functionality, but i want to show the toggle button as rounded corner.
To get a toggle button with rounded corners you can do the following :
Right click on the button and select Edit Template > Create a copy
Give your style a name
Search for the Border template in the resource code and set the corner radius to 33 (CornerRadius="33")
Hope this helps..!
In recent versions of UWP, ToggleButton exposes a CornerRadius property (thanks #Clint Rutkas).
Otherwise:
<ToggleButton
Background="Transparent"
FontSize="16"
IsChecked="{Binding IsEnabled, Mode=TwoWay}"
IsTabStop="False"
ToolTipService.ToolTip="Press to enable/disable metronome (Space)">
<ToggleButton.KeyboardAccelerators>
<KeyboardAccelerator Key="Space" />
<KeyboardAccelerator Key="P" />
</ToggleButton.KeyboardAccelerators>
<ToggleButton.Resources>
<x:String x:Key="Play"></x:String>
<x:String x:Key="Stop"></x:String>
<Style TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<Border
x:Name="border"
Width="56"
Height="56"
Padding="2"
Background="{TemplateBinding Background}"
BorderBrush="{ThemeResource ButtonBorderThemeBrush}"
BorderThickness="1"
CornerRadius="28">
<FontIcon x:Name="icon" Glyph="{StaticResource Play}" />
</Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding IsEnabled}" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="icon.Glyph" Value="{StaticResource Stop}" />
<Setter Target="icon.FontSize" Value="30" />
<Setter
Target="icon.Foreground"
Value="{ThemeResource SystemColorHighlightTextColor}" />
<Setter
Target="border.Background"
Value="{ThemeResource SystemColorHighlightColor}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Resources>
</ToggleButton>