WPF Button Style Background Image Swap on IsEnabled - wpf

We use a custom image for buttons in our project. We apply this via a style but now have a need to 'disable' the buttons and are trying to swap out the image for a new one.
The first Trigger works 100% as expected. When the button's IsEnabled == True, the button is 'green'. When the button's IsEnabled == False, the Green is removed and the Foreground color changes BUT the Grey image will not load up.
Am I missing something???
<Style TargetType="{x:Type Button}" x:Key="GreenGreyButton">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="..\Images\UI\Buttons\green.png"/>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="#FFA30046"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="..\Images\UI\Buttons\grey.png"/>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
</Style.Triggers>
</Style>

It's a pity that when the IsEnabled is false, the native style will override all settings (with the default gray background). You can however re-template the button like this:
<Style TargetType="{x:Type Button}" x:Key="GreenGreyButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Content}"
Margin="{TempateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="..\Images\UI\Buttons\green.png"/>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="#FFA30046"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="..\Images\UI\Buttons\grey.png"/>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
</Style.Triggers>
</Style>

Add the image as content to the button & use DatatTrigger instead, like this:
<Button...
>
<StackPanel>
<Image>
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" Value="True">
<Setter Property="Source" Value="..\Images\UI\Buttons\green.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" Value="False">
<Setter Property="Source" Value="..\Images\UI\Buttons\grey.png"/>
<Setter Property="Foreground" Value="Gray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</Button>

You need to set default values for your properties
<Style TargetType="{x:Type Button}" x:Key="GreenGreyButton">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="..\Images\UI\Buttons\green.png"/>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="#FFA30046"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="..\Images\UI\Buttons\grey.png"/>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
</Style.Triggers>

Related

Add border to radioButton with text on isChecked

I want to add border to radiobutton with text on isChecked
I tried Style.Trigger but it didn't seem to have action
Also tried via ControlTemplate.Trigger but referencing to both grid and text box says Parameter is not recognized
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style BasedOn="{StaticResource {x:Type ToggleButton}}"
TargetType="{x:Type RadioButton}"
x:Key="MenuButtonTheme">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
x:Name="GridMain">
<TextBlock Text="{TemplateBinding Property=Content}"
x:Name="ButtonText"
VerticalAlignment="Center"
Margin="20,0,0,0">
</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ButtonText" Property="Margin" Value="30,0,0,0"></Setter>
<!-- <Setter TargetName="ButtonText" Property="BorderThickness" Value="5"></Setter> -->
<!-- <Setter TargetName="GridMain" Property="BorderThickness" Value="5"></Setter> -->
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="GridMain" Property="Background" Value="#424549"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"></Setter>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="BorderThickness" Value="5"></Setter>
<Setter Property="BorderBrush" Value="#7289da"></Setter>
</Trigger>
</Style.Triggers>
</Style>
The TextBlock doesn't have a border, so it's impossible to set a value for the border either.
It can be solved in two ways.
Use instead of TextBlock element TextBox in read-only mode.
<ControlTemplate TargetType="RadioButton">
<Grid VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
x:Name="GridMain">
<TextBox Text="{TemplateBinding Content}"
x:Name="ButtonText"
VerticalAlignment="Center"
Margin="20,0,0,0"
IsReadOnly="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ButtonText" Property="Margin" Value="30,0,0,0"></Setter>
<Setter TargetName="ButtonText" Property="BorderThickness" Value="5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="GridMain" Property="Background" Value="#424549"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Since you have only one element in the panel, you can use Border instead.
<ControlTemplate TargetType="RadioButton">
<Border VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
x:Name="GridMain">
<TextBlock Text="{TemplateBinding Property=Content}"
x:Name="ButtonText"
VerticalAlignment="Center"
Margin="20,0,0,0">
</TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ButtonText" Property="Margin" Value="30,0,0,0"></Setter>
<Setter TargetName="GridMain" Property="BorderThickness" Value="5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="GridMain" Property="Background" Value="#424549"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

Remove underline from TabItem header when tabitem is selected

I want to underline the TabItem Header Title when Mousehover on header , and remove the Underline once it is selected.
I have tried below code:
<Style x:Key="N3EntityNavigationItemStyle" TargetType="{x:Type Custom11:TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" BorderThickness="0,0,1,0" BorderBrush="White" Padding="5,2">
<ContentPresenter x:Name="CP" ContentSource="Header">
</ContentPresenter>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="TextElement.Foreground" TargetName="CP" Value="Black"/>
<Setter TargetName="Border" Property="Background" Value="White" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}"></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" TextDecorations="Underline"></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But the tabitem header still remain underline after selecting the tab.

WPF "IsMouseOver" Trigger not Displaying Button Correctly

I have two png images, triple-checked to make sure they are properly transparent. Here is the button style code:
<Window.Resources>
<Style x:Key="TrackingButton" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers>
<!--Default Base-->
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Content">
<Setter.Value>
<Image Source="Resources/Start_Base.png"/>
</Setter.Value>
</Setter>
</Trigger>
<!--Hover-->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="Resources/Start_Hover.png"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
<!--Default Style-->
<Style.Setters>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Transparent"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="Transparent"/>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</Window.Resources>
Here is the default state of the button: DefaultState
But when hovered over, the button loses its transparency and a white border appears around the areas that are supposed to be transparent: HoveredOver
I'm not sure what's going on here..
If you want to get rid of the chrome, you could define your own custom ControlTemplate:
<Style x:Key="TrackingButton" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image x:Name="img" Source="Resources/Start_Base.png"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="img" Property="Source" Value="Resources/Start_Hover.png" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Remove ToggleButton backgroung on activate state

This is my ToggleButton:
<ToggleButton Width="100" Height="30" Margin="344,262,530,345" BorderThickness="2" Background="Transparent"
BorderBrush="#38abcf" FontFamily="Resources/#Buxton Sketch" Foreground="Gainsboro" FontSize="14">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content" Value="OFF"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="ON"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
Currently on activate state it's look like that:
And the Background color not changed although i set new property.
Update
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content" Value="Loops OFF"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Width="100" Height="30" BorderThickness="2" Background="Transparent" BorderBrush="#38abcf">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="Loops ON"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
Override default template
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content" Value="OFF"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Name="Border" Width="100" Height="30" BorderThickness="2" Background="Transparent"
BorderBrush="#38abcf">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Red" TargetName="Border" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="ON"/>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>

WPF Trigger and Binding problem

I am creating a button with a simple Polyline which I want to change color when the button is Disabled (btnUp.IsEnabled = false).
I tried this:
<RepeatButton x:Name="btnUp" Foreground="Green">
<RepeatButton.Style>
<Style TargetType="{x:Type RepeatButton}">
<Setter Property="Content">
<Setter.Value>
<Polyline x:Name="arrowUp" Points="0,2 3,0 6,2" Stroke="{Binding RelativeSource={RelativeSource AncestorType=RepeatButton}, Path=Foreground, Mode=TwoWay}" StrokeThickness="2"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#FFFFFFFF"/>
</Trigger>
</Style.Triggers>
</Style>
</RepeatButton.Style>
</RepeatButton>
But the Polyline still has the same (Green) color when the button is disabled. Even though I did expect it to be white because of the databinding between the button.foreground and polyline.stroke.
However if I change the trigger to this it works (the button is collapsed):
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
I found the answer on my own.
I moved the Foreground="Green" to a separate setter, <Setter Property="Foreground" Value="#FF383838"/> inside the <Style>, then it worked.
I'm not sure why though.
Here's the complete solution:
<RepeatButton x:Name="btnUp">
<RepeatButton.Style>
<Style TargetType="{x:Type RepeatButton}">
<Setter Property="Foreground" Value="Green"/>
<Setter Property="Content">
<Setter.Value>
<Polyline x:Name="arrowUp" Points="0,2 3,0 6,2" Stroke="{Binding RelativeSource={RelativeSource AncestorType=RepeatButton}, Path=Foreground, Mode=TwoWay}" StrokeThickness="2"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#FFFFFFFF"/>
</Trigger>
</Style.Triggers>
</Style>
</RepeatButton.Style>
</RepeatButton>

Resources