Set icon color in toggle button depending on toggle button state - xaml

I got a problem with my ToggleButton and its content.
I hope this information is sufficient, let me know if you need anything else!
Problem
I have a ToggleButton that contains a FontIcon and a TextBlock in a Grid:
<ToggleButton Grid.Row="1" HorizontalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<FontIcon Grid.Column="0"
FontSize="20"
Glyph="{StaticResource mdi_handyman}"
FontFamily="{StaticResource MaterialDesignIconsOutlined}"/>
<TextBlock Grid.Column="1" Margin="10,0,0,0" Text="{x:Bind p:Resources.Dashboard_Maintenance}"/>
</Grid>
</ToggleButton>
The text in the ToggleButton should always be white. That's why I set following resources for the ToggleButton:
<SolidColorBrush x:Key="ToggleButtonForeground" Color="{ThemeResource WhiteColor}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundDisabled" Color="{ThemeResource WhiteColor}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundPointerOver" Color="{ThemeResource WhiteColor}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundChecked" Color="{ThemeResource RichBlackColor}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPointerOver" Color="{ThemeResource RichBlackColor}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundPressed" Color="{ThemeResource WhiteColor}"/>
<SolidColorBrush x:Key="ToggleButtonBackground" Color="{ThemeResource RichBlackColor}"/>
<SolidColorBrush x:Key="ToggleButtonBackgroundDisabled" Color="{ThemeResource RichBlackColor}"/>
<SolidColorBrush x:Key="ToggleButtonBackgroundPointerOver" Color="{ThemeResource LightPrussianBlueColor}"/>
<SolidColorBrush x:Key="ToggleButtonBackgroundChecked" Color="{ThemeResource VividSkyBlueColor}"/>
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedDisabled" Color="{ThemeResource PaleVividSkyBlueColor}"/>
<SolidColorBrush x:Key="ToggleButtonBackgroundCheckedPointerOver" Color="{ThemeResource VividSkyBlueColor}"/>
<SolidColorBrush x:Key="ToggleButtonBackgroundPressed" Color="{ThemeResource LightPrussianBlueColor}"/>
Now there is the requirement to add the FontIcon in the Grid as well. But this FontIcon behaves the same as the text (obviously as the resources for the ToggleButton foreground are for the whole content).
However the FontIcon needs following behavior in the ToggleButton:
<SolidColorBrush x:Key="ToggleButtonForeground" Color="{ThemeResource VividSkyBlue}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundDisabled" Color="{ThemeResource VividSkyBlue}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundPointerOver" Color="{ThemeResource VividSkyBlue}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundChecked" Color="{ThemeResource RichBlackColor}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundCheckedPointerOver" Color="{ThemeResource RichBlackColor}"/>
<SolidColorBrush x:Key="ToggleButtonForegroundPressed" Color="{ThemeResource WhiteColor}"/>
My guess
I guess I could solve this with a converter for the FontIcon Foreground that binds to the selected state of the ToggleButton but this converter would also need the disabled state of the ToggleButton which makes this a bit more compley.
As I think I would be able to get this running I think this might be a bit hacky and not satisfying.
Does anyone have an idea how to solve this more elegant?
Thank you in advance!

You can use the Microsoft.Xaml.Behaviors.WinUI.Managed NuGet package.
Here's the code but I changed the colors to check if this works.
<FontIcon
x:Name="ThisFontIcon"
Grid.Column="0"
FontSize="20"
Glyph="{StaticResource CheckBoxCheckedGlyph}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="PointerEntered">
<core:ChangePropertyAction
PropertyName="Foreground"
TargetObject="{Binding ElementName=ThisFontIcon}"
Value="HotPink" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="PointerExited">
<core:ChangePropertyAction
PropertyName="Foreground"
TargetObject="{Binding ElementName=ThisFontIcon}"
Value="{ThemeResource SystemAccentColor}" />
</core:EventTriggerBehavior>
<core:DataTriggerBehavior
Binding="{Binding IsChecked, ElementName=ThisToggleButton}"
Value="True">
<core:ChangePropertyAction
PropertyName="Foreground"
TargetObject="{Binding ElementName=ThisFontIcon}"
Value="{ThemeResource SystemChromeBlackHighColor}" />
</core:DataTriggerBehavior>
<core:DataTriggerBehavior
Binding="{Binding IsChecked, ElementName=ThisToggleButton}"
Value="False">
<core:ChangePropertyAction
PropertyName="Foreground"
TargetObject="{Binding ElementName=ThisFontIcon}"
Value="{ThemeResource SystemAccentColor}" />
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</FontIcon>

Related

ToggleMenuFlyoutItem Resources do not apply

I am currently trying to style a MenuFlyout using ToggleMenuFlyoutItems here are the resources of ToggleMenuFlyoutItems listed.
If I override those resources nothing changes.
These are my desired resources and colors.
<SolidColorBrush x:Key="ToggleMenuFlyoutItemBackground" Color="{ThemeResource WhiteColor}"/>
<SolidColorBrush x:Key="ToggleMenuFlyoutItemBackgroundPointerOver" Color="{ThemeResource VividSkyBlueColor}"/>
<SolidColorBrush x:Key="ToggleMenuFlyoutItemBackgroundPressed" Color="{ThemeResource StarCommandBlueColor}"/>
<SolidColorBrush x:Key="ToggleMenuFlyoutItemBackgroundDisabled" Color="{ThemeResource LightBlackColor}"/>
<SolidColorBrush x:Key="ToggleMenuFlyoutItemForeground" Color="{ThemeResource PitchBlackColor}"/>
<SolidColorBrush x:Key="ToggleMenuFlyoutItemForegroundPointerOver" Color="{ThemeResource PitchBlackColor}"/>
<SolidColorBrush x:Key="ToggleMenuFlyoutItemForegroundPressed" Color="{ThemeResource PitchBlackColor}"/>
<SolidColorBrush x:Key="ToggleMenuFlyoutItemCheckGlyphForeground" Color="{ThemeResource TabascoRedColor}"/>
<SolidColorBrush x:Key="ToggleMenuFlyoutItemCheckGlyphForegroundPointerOver" Color="{ThemeResource VikingGreenColor}"/>
<SolidColorBrush x:Key="ToggleMenuFlyoutItemCheckGlyphForegroundPressed" Color="{ThemeResource PitchBlackColor}"/>
is this a known problem or does anyone no a reason/solution?
Greetings

XAML Theme not getting the Background color property

I have a button that uses my own theme by using style= I want the theme code to pick up and use the Background color property but everything I've tried always fetches black #000000 from the XAML code.
I use it like this:
<Button Background="#844eff" Style="{StaticResource PosButtonTheme}" Content="Return
Sale" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,44,0,0" />
My theme code looks like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style BasedOn="{StaticResource {x:Type Button}}"
TargetType="{x:Type Button}"
x:Key="PosButtonTheme">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<StackPanel
Margin="0,0,0,0">
<Border Width="62" Height="62">
<Border.Background>
<LinearGradientBrush StartPoint ="0,0" EndPoint ="1,2">
<GradientStop Color= "{TemplateBinding Property=Background}" Offset="0.0"/>
<GradientStop Color= "#FFFFAF" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<Border.Clip>
<RectangleGeometry RadiusX="7" RadiusY="10" Rect="0,0,62,62"/>
</Border.Clip>
<Grid>
<StackPanel>
<TextBlock Text= "{TemplateBinding Property=Content}" TextAlignment="Center" Foreground="White" FontSize="14" FontFamily="Barlow Semi Condensed SemiBold" FontWeight="SemiBold" Margin=" 0,15,0,0"/>
</StackPanel>
</Grid>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
The "{TemplateBinding Property=Content}" works fine in the TextBlock but "{TemplateBinding Property=Background}" seems to do nothing its always black or #000000
Any ideas?
You code is ok, so I think you miss to set the BackGround property.
This is what I tried:
Background = Brushes.Red;
and then
Background = Brushes.Blue;
if this not work for you check this https://stackoverflow.com/a/6748306/3464775

NavigationView Hamburger button style

I am working on an app that uses a navigationview. I updated Uno to the latest prerelease(Uno 3.0.0-dev.405)- and today after updating Uno, the Hamburger button/Toggle button no longer has the same color as the rest of the menuitems- it is black. I added in the PaneButtonStyle - but that did not work either. How do I fix this?
<NavigationView x:Name="NavView"
Loaded="NavView_Loaded"
ItemInvoked="NavView_ItemInvoked"
PaneDisplayMode="LeftCompact" IsPaneOpen="False"
IsBackButtonVisible="Collapsed"
BackRequested="NavView_BackRequested"
Foreground="{StaticResource NavigationViewItemForeground}"
Background="{StaticResource NavigationViewDefaultPaneBackground}"
PaneToggleButtonStyle="{StaticResource PaneToggleButtonColor}"
Grid.Row="1" >
Style- in separate Resource Dictionary:
<Color x:key="PaneToggleButtonColor">#FF0A8000</Color>
<SolidColorBrush x:Key="NavigationViewDefaultPaneBackground" Color="#FFF2F2F2"/>
<SolidColorBrush x:Key="NavigationViewItemForeground" Color="Green"/>
<SolidColorBrush x:Key="NavigationViewItemForegroundSelected" Color="Green"/>
<SolidColorBrush x:Key="NavigationViewItemForegroundSelectedPointerOver" Color="Green"/>
<SolidColorBrush x:Key="NavigationViewItemForegroundPressed" Color="Green"/>
<SolidColorBrush x:Key="NavigationViewItemForegroundSelectedPressed" Color="Green"/>
<SolidColorBrush x:Key="NavigationViewSelectionIndicatorForeground" Color="DarkOrange" />

How to animate a Popup when it hides?

i created a Popup Style for using in my windows 8.1 application. And i applied PopupThemeTransition to it's ChildTransitions Property.
<Style x:Key="AnimatedPopupStyle" TargetType="Popup">
<Setter Property="IsLightDismissEnabled" Value="False"/>
<Setter Property="ChildTransitions">
<Setter.Value>
<TransitionCollection>
<PopupThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
My problem is that it animates when it Opens & not animating when closing. What to do with that for animating the content on hiding ? Do i want to create a Custom Popup control?
NB: I know that PopInThemeAnimation & PopOutThemeAnimation is there . But don't know how to use it on this condition ?
This is not native to the Popup because they typically do not have an exit animation. Having said that, there's no reason you can't add an exit animation to a Popup control.
Try this:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.Resources>
<Storyboard x:Name="ShowPopup">
<PopInThemeAnimation Storyboard.TargetName="MyPopup" />
</Storyboard>
<Storyboard x:Name="HidePopup">
<PopOutThemeAnimation Storyboard.TargetName="MyPopup" />
</Storyboard>
</Grid.Resources>
<Popup x:Name="MyPopup" IsOpen="True"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Popup.Transitions>
<TransitionCollection>
<PopupThemeTransition />
</TransitionCollection>
</Popup.Transitions>
<Grid Height="200" Width="200" Background="Red">
<StackPanel>
<Button Content="Hide (Native)" HorizontalAlignment="Center">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:ChangePropertyAction
PropertyName="IsOpen"
TargetObject="{Binding ElementName=MyPopup}" />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
<Button Content="Hide (Storyboard)" HorizontalAlignment="Center">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Media:ControlStoryboardAction
Storyboard="{StaticResource HidePopup}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</StackPanel>
</Grid>
</Popup>
<StackPanel>
<Button Content="Show Popup (Native)" HorizontalAlignment="Left" VerticalAlignment="Top">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:ChangePropertyAction
TargetObject="{Binding ElementName=MyPopup}"
PropertyName="IsOpen" Value="True"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
<Button Content="Show Popup (Storyboard)" HorizontalAlignment="Left" VerticalAlignment="Top">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:ChangePropertyAction
TargetObject="{Binding ElementName=MyPopup}"
PropertyName="IsOpen" Value="True"/>
<Media:ControlStoryboardAction
Storyboard="{StaticResource ShowPopup}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</StackPanel>
</Grid>
Using these:
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
xmlns:Media="using:Microsoft.Xaml.Interactions.Media"
Best of luck!

XAML ListView - Change Image Source for selected item

I'm using a ListView with a Custom Template, something like this:
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Center" Width="220" Height="220">
<Image x:Name="image" Stretch="UniformToFill"
Source="{Binding Brand.Image,
ConverterParameter=transparent,
Converter={StaticResource LogoToUriConverter}}"/>
<StackPanel VerticalAlignment="Bottom">
<TextBlock Text="{Binding Name}"
Foreground="{StaticResource ApplicationColor}"
Style="{StaticResource TitleTextStyle}"
Height="30" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Name}"
Foreground="{StaticResource ApplicationColor}"
Style="{StaticResource CaptionTextStyle}"
TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
Now when an Item is selected I would like to have the image source for selected item changed to a new one.
Brand.Image is not a DependencyProperty because it comes from an external DataObject.
So, I think that in WPF I could use a Trigger to change it manually.
But since in winRT it does not work anymore, I've looked into VSM, but I'm not figuring out how can I accomplish that.
Can someone provide me a real example how could it be done?
Thank you
I was able to solve this, in a tricky way, but I got it to work:
Using an ExtendedVisualStateManager, (it was available for .NET through ExpressionBlend dlls, but not for WinRT, so I got it from here: http://nroute.codeplex.com/SourceControl/changeset/69480#nRoute5/nRoute.Framework.Metro/Components/ExtendedVisualStateManager.cs)
Having that I just catch an OnSelected Event and use the new VisualStateManager to do that:
ExtendedVisualStateManager.GoToElementState(sender as Grid, "Selected2", true);
Here's the full XAML for the ItemTemplate:
<DataTemplate>
<Grid x:Name="ItemGrid" HorizontalAlignment="Center" Width="220" Height="220" PointerPressed="GridItemTapped">
<Image x:Name="image" Stretch="UniformToFill" Source="{Binding Brand.Name, ConverterParameter=white, Converter={StaticResource LogoToUriConverter}}"/>
<Image x:Name="image_colored" Stretch="UniformToFill" Visibility="Collapsed" Source="{Binding Brand.Name, ConverterParameter=colored, Converter={StaticResource LogoToUriConverter}}"/>
<StackPanel VerticalAlignment="Bottom">
<TextBlock Text="{Binding Name}" Foreground="White" Style="{StaticResource TitleTextStyle}" Height="30" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Name}" Foreground="White" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
<VisualStateManager.CustomVisualStateManager>
<vsm:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Selected2">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="00:00:00.0000000">
<DiscreteObjectKeyFrame.Value>
Collapsed
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image_colored" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="00:00:00.0000000">
<DiscreteObjectKeyFrame.Value>
Visible
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
Hope this can help anybody with the same issue.
If you have a better and easier way to achieve the same result in WinRT, please present your solution.
Thank you
You can create a style for your ListViewItem, with a controltemplate for the triggers and a datatemplate for your data binding, like this:
<Style x:Key="FocusedContainer" TargetType="{x:Type ListViewItem}">
<EventSetter Event="GotKeyboardFocus" Handler="OnListBoxItemContainerFocused" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="backgroundBorder">
<ContentPresenter Content="{TemplateBinding Content}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Center" Width="220" Height="220">
<Image x:Name="image" Stretch="UniformToFill" Source="{Binding Brand.Image, ConverterParameter=transparent, Converter={StaticResource LogoToUriConverter}}"/>
<StackPanel VerticalAlignment="Bottom">
<TextBlock Text="{Binding Name}" Foreground="{StaticResource ApplicationColor}" Style="{StaticResource TitleTextStyle}" Height="30" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Name}" Foreground="{StaticResource ApplicationColor}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="image" Property="Source" Value="{**Insert your alternate binding here**}"
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then configure your ListView like this:
<ListView ItemContainerStyle="{StaticResource FocusedContainer}"/>
You'll see that the style has an EventSetter: its purpose is to get the correct item selected even if you click inside some control (not directly on the background). You need to create the handler in code behind, just a couple of lines:
private void OnListBoxItemContainerFocused(object sender, System.Windows.RoutedEventArgs e)
{ (sender as ListViewItem).IsSelected = true; }
Hope this is helpful, regards!