How to change selected Flyoutitem background color - c#

How do I change color of a selected FlyOutItem ? Let's say I want it to be blue instead of gray in the screenshot below.
I downloaded a few sample projects like Gastropods and went through all FlyOutItem styling properties ( it seems ) but can't figure it out.

Solution :
You can add a style of Item .
In Shell.Resource
<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="Red"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
And use it in Shell.ItemTemplate
<Shell.ItemTemplate>
<DataTemplate >
<Grid Style="{StaticResource FloutItemStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding FlyoutIcon}"
Margin="5"
HeightRequest="45" />
<Label Grid.Column="1"
Text="{Binding Title}"
FontAttributes="Italic"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>

Related

Change colour of icon and text if selected in FlyoutItem

I am trying to implement a sidebar that would have icons from font and while selecting one of them text of Label and Icon colour would change. I was able to implement this partly, but can't figure out how to:
Apply background colour to Flyout (currently it is still default black in NET7)
Change colour of icon if it is selected (currently colour does not change change on selection)
Change colour of Label text if it is selected (currently colour does not change change on selection)
Currently I have this:
I want to achieve this for selected item also FlyoutBackground="#111111" has no effect for some reason:
App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
<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="Transparent"/>
<Setter TargetName="_label" Property="Label.TextColor" Value="Red" />
<Setter TargetName="_image" Property="Image.Source" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>
<Application.MainPage>
<Shell FlyoutWidth="90" FlyoutBehavior="{OnIdiom Phone=Disabled, Default=Locked}"
FlyoutBackground="#111111">
<Shell.FlyoutHeaderTemplate>
<DataTemplate>
<BoxView HeightRequest="50" Color="Transparent"/>
</DataTemplate>
</Shell.FlyoutHeaderTemplate>
<!-- Desktop/Tablet-->
<FlyoutItem Title="Home" Icon="{FontImage FontFamily=FontAwesomeSolid, Glyph={x:Static helpers:FontAwesomeIcons.User}, Size=50, Color=Red}">
<ShellContent Title="Page1" Route="Page1" ContentTemplate="{DataTemplate page:Page1}">
<ShellContent.Icon>
<FontImageSource FontFamily="FontAwesomeSolid" Glyph="{x:Static helpers:FontAwesomeIcons.User}" Color="Red" Size="50"/>
</ShellContent.Icon>
</ShellContent>
</FlyoutItem>
<FlyoutItem Title="Settings" Icon="{FontImage FontFamily=FontAwesomeSolid, Glyph={x:Static helpers:FontAwesomeIcons.User}, Size=50}">
<ShellContent Title="Page2" Route="Page2" ContentTemplate="{DataTemplate page:Page2}">
<ShellContent.Icon>
<FontImageSource FontFamily="FontAwesomeSolid" Glyph="{x:Static helpers:FontAwesomeIcons.User}" Color="White" Size="50"/>
</ShellContent.Icon>
</ShellContent>
</FlyoutItem>
<Shell.ItemTemplate>
<DataTemplate>
<Grid Style="{StaticResource FloutItemStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<Image Source="{Binding FlyoutIcon}"
Grid.Row="0"
HeightRequest="40"
Margin="5,0,5,0"
HorizontalOptions="CenterAndExpand"
x:Name="_image"/>
<Label Grid.Row="1"
Text="{Binding Title}"
TextColor="White"
FontSize="Body"
Padding="7,0,7,0"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
x:Name="_label">
</Label>
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
</Shell>
</Application.MainPage>
You can use Style FlyoutItem and MenuItem objects.
In AppShell.xaml:
<Shell.Resources>
<ResourceDictionary>
<Style Class="FlyoutItemLabelStyle" TargetType="Label"/>
<Style TargetType="Image" Class="FlyoutItemImageStyle"/>
<Style x:Key="dd" Class="FlyoutItemLayoutStyle" 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="{AppThemeBinding Dark=White,Light=Black}" />
<Setter TargetName="FlyoutItemImage" Property="Image.BackgroundColor" Value="white" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Transparent"/>
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Red" />
<Setter TargetName="FlyoutItemImage" Property="Image.BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ResourceDictionary>
</Shell.Resources>
<Shell.ItemTemplate>
<DataTemplate>
<Grid Style="{StaticResource dd}">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<Image Source="{Binding FlyoutIcon}"
Grid.Row="0"
HeightRequest="40"
Margin="5,0,5,0"
HorizontalOptions="Center"
x:Name="FlyoutItemImage"/>
<Label Grid.Row="1"
Text="{Binding Title}"
FontSize="Body"
Padding="7,0,7,0"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
x:Name="FlyoutItemLabel"/>
</Grid>
</DataTemplate>
</Shell.ItemTemplate>

Xamarin Shell Navigation Flyout Selected Label Color Not Changing

here is my code in shell.xaml selected frame colour for flyout item is working for me its green it showing well but for the selected label it is same as normal
flyout label color i dont know what i am missing here
this is for flyout item frame
<Style x:Key="FloutItemStyle" TargetType="Frame">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="#384a1a"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
this is for label style
<Style x:Key="FloutItemStyles" TargetType="Label">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="TextColor" Value="#6b6b6b"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="TextColor" Value="#fff"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
this my template
<Shell.FlyoutHeaderTemplate>
<DataTemplate>
<Grid HeightRequest="110">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<FlexLayout x:Name="imageHolder" AlignItems="Center" JustifyContent="Center" Padding="20,10" BackgroundColor="#fff">
<Image Source="logo.png" />
<Label TextColor="#6b6b6b" x:Name="UserName"></Label>
</FlexLayout>
</Grid>
</DataTemplate>
</Shell.FlyoutHeaderTemplate>
<Shell.ItemTemplate >
<DataTemplate >
<Frame Style="{StaticResource FloutItemStyle}" Padding="25,5">
<FlexLayout Margin="0,5" AlignItems="Center" JustifyContent="Start">
<Frame Padding="5" HeightRequest="30" WidthRequest="30" CornerRadius="100"> <Image Source="{Binding FlyoutIcon}"
Margin="5"
WidthRequest="30"
HeightRequest="30" />
</Frame>
<Label Style="{StaticResource FloutItemStyles}" Padding="25,0,0,0"
Text="{Binding Title}"
FontAttributes="Bold"
FontSize="18"
VerticalTextAlignment="Center" />
</FlexLayout>
</Frame>
</DataTemplate>
</Shell.ItemTemplate>
I think it has to do with the label being inside the frame, and this causes that the label state does not change
If you want to trigger several changes upon selection you can check the Microsoft documentation about the flyout styling combined with this other example
In this way, when the flyout item gets selected, it triggers all the changes that you want, refering to the element by their name

Xamarin Forms Shell ItemTemplate Style

How to change lable's color which is inside grid of FlyoutItem?
In the above code I tried to change grid's background color and lable's font color when a specific menu item is selected. Grid's background changes. But font color doesn't.
Styles:
<Shell.Resources>
<Style x:Key="FloutItemStyle" TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Orange"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="DarkOrange"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style x:Key="FlyoutLabelStyle" TargetType="Label">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="TextColor" Value="Black"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="TextColor" Value="DarkGray"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</Shell.Resources>
Shell ItemTemplate:
<DataTemplate >
<Grid Style="{StaticResource FloutItemStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding FlyoutIcon}"
Margin="5"
HeightRequest="45" />
<Label Style="{StaticResource FlyoutLabelStyle}"
Grid.Column="1"
FontSize="Large"
Text="{Binding Title}"
FontAttributes="Bold"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
You can try using Triggers.
<Label Grid.Column="1"
TextColor="Black"
Text="{Binding Title}"
FontAttributes="Italic"
VerticalTextAlignment="Center" >
<Label.Triggers>
<DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference grid},Path=BackgroundColor}" Value="Accent">
<Setter Property="TextColor" Value="White"/>
</DataTrigger>
</Label.Triggers>
</Label>
for reference

How to change properties of a grid with visual state manager XAML

I am developing a windows universal application using C# and XAML. When my app is run on a laptop I want to change the height of my child grid in this gridview named tabIcon.
<Grid Name="tabGrid" Width="700">
<GridView Name="SpecialtyGridView" HorizontalAlignment="Center" ItemsSource="{Binding Source={StaticResource SpecialtyCollectionViewSource}}" Grid.Row="2" SelectionMode="None" IsItemClickEnabled="True" ItemClick="SpecialtyGridView_ItemClick">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Margin="0,0,0,10" Orientation="Vertical" MaximumRowsOrColumns="4"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<Grid Name="tabIcon" Background="#21539E" Width="290" Height="140" Margin="5,0,5,8">
<TextBlock x:Name="SpecialityTextBlock" FontSize="26" Foreground="White" FontFamily="Segoe UI" VerticalAlignment="Center" HorizontalAlignment="Center">
<Run Text="{Binding speciality}"/>
</TextBlock>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
I use a visual state trigger to do this but it does not work. Here is my trigger code for laptop.
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Phone">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth = "0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target = "HeaderGrid.Height"
Value = "90" />
<Setter Target = "Instruction.Visibility"
Value = "Collapsed" />
<Setter Target = "TheatreName.FontSize"
Value = "14" />
<Setter Target = "TheatreName.HorizontalAlignment"
Value = "Left" />
<Setter Target = "TheatreName.Margin"
Value = "0,40" />
<Setter Target = "PatientNameAndIDStackPanel.Margin"
Value = "10,0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Tablets">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth = "720" />
</VisualState.StateTriggers>
<VisualState.Setters>
<!--<Setter Target = "Body.Background"
Value = "Red" />-->
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Laptop">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth = "1024" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target = "tabIcon.Height"
Value = "60" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PCs">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth = "1400" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target = "Divider.Height"
Value = "80" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
This code works if I use it for the grid named tabGrid but does not work for the grid named tabIcon. What can I do to get this to work?
Is there any reason, why you need to do this just in XAML?
If not, just make two DataTemplates and change it on SizeChanged event of your page or parent grid.
XAML
<Page SizeChanged="MainPage_OnSizeChanged">
<Page.Resources>
<DataTemplate x:Key="LaptopTemplate">
<Grid Background="#21539E" Width="290" Height="60" Margin="5,0,5,8">
<TextBlock x:Name="SpecialityTextBlock"
FontSize="26" Foreground="White"
FontFamily="Segoe UI"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<Run Text="{Binding speciality}"/>
</TextBlock>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DesktopTemplate">
<Grid Name="tabIcon" Background="#21539E" Width="290" Height="40" Margin="5,0,5,8">
<TextBlock x:Name="SpecialityTextBlock"
FontSize="26"
Foreground="White"
FontFamily="Segoe UI"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<Run Text="{Binding speciality}"/>
</TextBlock>
</Grid>
</DataTemplate>
</Page.Resources>
<GridView x:Name="SpecialtyGridView">
</GridView>
</Page>
Code-behind
private void MainPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
if (e.PreviousSize != e.NewSize)
{
if (MainPage.ActualWidth > 1024)
{
SpecialtyGridView.ItemTemplate = Resources["DesktopTemplate"] as DataTemplate;
}
else
{
SpecialtyGridView.ItemTemplate = Resources["LaptopTemplate"] as DataTemplate;
}
}
}
EDIT
Or you can even do it in VisualStateManager:
<VisualStateGroup>
<VisualState x:Name="Laptop">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="SpecialtyGridView.ItemTemplate" Value="{StaticResource LaptopTemplate}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Desktop">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1024" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="SpecialtyGridView.ItemTemplate" Value="{StaticResource DesktopTemplate}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>

Visual State Manager in Windows 10 UWP not applying initial state on page load

I have a page with a relative panel to re-organize based on width. However, it doesn't seem to apply any state at load unless the width is > 720px. If I resize the page after it's loaded both states work.
A workaround would be to check the window size on page loaded and manually choose the state, but I believe this should be handled automatically? I have other pages that work, I'm not sure what I'm doing different. Here is a simplified version of my code, I have it set red/blue backgrounds so I can tell if/which state is being applied
<Page.Resources>
<converters:HighlightConverter x:Key="HighlightConverter"/>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<gui:MainAppBar x:Name="mainAppBar" Grid.Row="0"/>
<ScrollViewer Grid.Row="1">
<RelativePanel>
<StackPanel x:Name="ZonesContainer" Margin="12,12,0,0">
<TextBlock Text="Zones"/>
<ItemsControl x:Name="ZonesPanel">
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="6"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid x:Name="ZonesWrapGrid" Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="Panel" Orientation="Horizontal">
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<StackPanel x:Name="SourcesContainer" RelativePanel.RightOf="ZonesContainer" Margin="12,12,0,0">
<GridView x:Name="SourcesPanel" Header="Sources">
</GridView>
</StackPanel>
<StackPanel x:Name="NetworkServicesContainer" RelativePanel.Below="SourcesContainer" RelativePanel.AlignLeftWith="SourcesContainer" Margin="12,12,0,0">
<GridView x:Name="NetworkServicesPanel" Header="Network">
</GridView>
</StackPanel>
</RelativePanel>
</ScrollViewer>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="WindowStates">
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ZonesContainer.Background" Value="Blue"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ZonesContainer.Background" Value="Red"/>
<Setter Target="SourcesContainer.(RelativePanel.Below)" Value="ZonesContainer" />
<Setter Target="SourcesContainer.(RelativePanel.AlignLeftWith)" Value="ZonesContainer" />
<Setter Target="NetworkServicesContainer.(RelativePanel.Below)" Value="SourcesContainer" />
<Setter Target="ZonesWrapGrid.Orientation" Value="Horizontal" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
Update
I've updated the code to show the missing ZonesWrapGrid, it does seem to be related. The visual states do work on it when I resize the page it will switch the ZonesWrapGrid orientation, just no state set on load.
However, if I remove the ZonesWrapGrid change from the visual state manager the narrow/wide states do correctly apply on load, but of course I lose the orientation change I want.
Can you try just replacing the whole ItemsPanelTemplate? Create both in resources:
<ItemsPanelTemplate x:Key="VerticalWrapGrid">
<ItemsWrapGrid Orientation="Vertical"/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="HorizontalWrapGrid">
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
And then swap when needed:
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ZonesPanel.ItemsPanel" Value="{StaticResource HorizontalWrapGrid}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ZonesPanel.ItemsPanel" Value="{StaticResource VerticalWrapGrid}" />
</VisualState.Setters>
</VisualState>

Categories

Resources