WPF Data Trigger - c#

Hi I just wondered if I could get some help, I'm having alot of trouble getting the data trigger to work, if i remove the data trigger and place the drop shadow just as a setter it works. But i want to be able to give the user the option of turning on and off the drop shadow so I thought the data trigger would be the answer.
Basically I want to add the data trigger all over my control styles and just be able to change the fancyGraphics BOOL to TRUE or FALSE and have every controls drop shadow adjust.
Thanks in advance.
Here is my XAML
<sys:Boolean x:Key="fancyGraphics" >True</sys:Boolean>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#EEE"></Setter>
<Setter Property="Foreground" Value="#555"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderThickness="1" BorderBrush="#DDD">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#333"></Setter>
<Setter Property="BorderBrush" Value="#888"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=fancyGraphics}" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="20"
Opacity="0.5"
ShadowDepth="0"
Color="#111" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>

The binding in DataTrigger looks for a property named fancyGraphics. But, fancyGraphics is a static resource. You should define the binding as such:
<DataTrigger Binding="{Binding Source={StaticResource fancyGraphics}}" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="20"
Opacity="0.5"
ShadowDepth="0"
Color="#111" />
</Setter.Value>
</Setter>
</DataTrigger>

Related

button trigger event dont work for border?

I search a lot about how to create a template for button in wpf for avoid or override default mouse over event and i create my own template ( with help of others codes ) but my codes dont work probably. i want to change background color and change border appreance but border trigger dont work. please check my codes and guide me to fix it thanks.
<Button x:Name="AccountBtn" Width="250" Height="100" Margin="5 5 5 5" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="Myborder" BorderThickness="1 1 1 1" BorderBrush="#EDEDED" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="LightGray"/>
<Setter Property="BorderThickness" Value="2 2 2 2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
The proper code would be the following
<Button x:Name="AccountBtn" Width="250" Height="100" Margin="5 5 5 5" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="BorderThickness" Value="1 1 1 1"/>
<Setter Property="BorderBrush" Value="#EDEDED"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="Myborder"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
<Setter Property="BorderBrush" Value="LightGray"/>
<Setter Property="BorderThickness" Value="2 2 2 2"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
The problem with your code is not that the trigger isn't working. The trigger is working as it should, but the values of BorderBrush and BorderThickness properties are ignored in your template!
So I changed the code in such a way that
the values of BorderBrush and BorderThickness are taken from the Button's properties,
the initial values are set in the style, and
(optional) moved the triggers from the control template directly to the style.
That's all!

Check Toggle button state and manual trigger it using C#

I am trying to trigger ToggleButton programmatically using C#.
I have a ToggleButton the switch imaged between muted and unmuted. If I toggle the button to muted I have the expected image but if I change the VolumeBar I have to trigger the button from C# because if doesn't do it automatically.
<ToggleButton x:Name="MuteBtn" Height="20" Width="20" Background="Transparent" Click="MuteButton_Click">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content">
<Setter.Value>
<Image Source="/Resources/audio-volume_on.ico" />
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="/Resources/volume_off.ico" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
I have a class called VolumeBar_ValueChanged that has to Toggle the button based on the VolumeBar Value.
As #Anu Viswan said, The isChecked property may solve your problem.
Try to use ControlTemplate for ToggleButton.
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Image x:Name="borderImage" Source="Image1.jpg"/>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Source" Value="Image2.jpg" TargetName="borderImage"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>

Why isnt my button using the style I created?

So I decided to try to give a button a custom style.
Yet when I assign it the Style it wont use it, why is this?
I tried creatinga button with a textbox, image and a ellipse with a label on that too.
I want the button to change color when I hover over it but its making my button disappear.
Window resources
<Window.Resources>
<Style x:Key="MenuButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ControlTemplate.Triggers>
<Trigger Property="Background" Value="#272727">
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Gray"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
And then the button
<Button Background="Transparent"
Style="{StaticResource MenuButton}"
Height="25"
BorderThickness="0">
<StackPanel Orientation="Horizontal">
<Image Source="Resources/earth-globe.png"
Height="20"
Width="20"
HorizontalAlignment="Left"
Margin="0,0,5,0"
UseLayoutRounding="True"
RenderOptions.BitmapScalingMode="Fant"/>
<Label Content="Websites"
Foreground="White"
VerticalAlignment="Center"
Width="100"
Height="24"/>
<Grid HorizontalAlignment="Right" Height="20" Width="20">
<Ellipse Width="20"
Height="20"
Fill="#555555"
Margin="0,0,0,0">
</Ellipse>
<TextBlock Text="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="12"
TextAlignment="Center"
Foreground="White"/>
</Grid>
</StackPanel>
</Button>
You do not want to put that style in the template portion of the style because a template is used for customizing the full control look (i.e. making a button a circle) and a way of giving the developer more flexibility over styling. What you could do is make a style that is applied to the button. Instead try this:
<Window.Resources>
<Style x:Key="MenuButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="#272727" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Gray" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
If you did want to modify the template property though, also a valid approach you need to add a <ContentPresenter />. See the below example:
<Window.Resources>
<Style x:Key="MenuButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter />
<ControlTemplate.Triggers>
<Trigger Property="Background" Value="#272727">
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Gray"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
However, with the minimal styling you have it seems like a poor use case to modify the template and I would recommend the first approach.
Add missing ContentPresenter to your DataTemplate.
<Style x:Key="MenuButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter /> <!--This thing was missing-->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="RED" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Background does not change of button C# WPF

I am trying to change style on mouseover.
My Code is:
<Button Name="register" Content="Register" Margin="15,410,20,0" Padding="6" FontSize="18" VerticalAlignment="Top" Background="#FF0090D6" BorderBrush="#FF0090D6" Foreground="White">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
But the Background is the same default thing. But when i change property to BorderThickness then it works.
What am i doing wrong?
In the default template of button, there is trigger in ControlTemplate which set Background of button to #FFBEE6FD and since control template triggers have higher precedence compared to Style triggers that's why your trigger never works.
For that to achieve you have to override default template of button and remove that trigger from it so that your style trigger gets applied.
Here is the default template with that specific trigger commented out. In case you want to override BorderBrush as well, get rid of it as well from the template.
<ControlTemplate x:Key="DefaultTemplateOfButton" TargetType="ButtonBase">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
Name="border"
SnapsToDevicePixels="True">
<ContentPresenter RecognizesAccessKey="True"
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
Name="contentPresenter"
Margin="{TemplateBinding Control.Padding}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
Focusable="False" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsDefaulted" Value="True">
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<!--<Setter Property="Panel.Background" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFBEE6FD</SolidColorBrush>
</Setter.Value>
</Setter>-->
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FF3C7FB1</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ButtonBase.IsPressed" Value="True">
<Setter Property="Panel.Background" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFC4E5F6</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FF2C628B</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Panel.Background" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFBCDDEE</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FF245A83</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="Panel.Background" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFF4F4F4</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFADB2B5</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter">
<Setter.Value>
<SolidColorBrush>#FF838383</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
How to set the control template to button?
Define the template somewhere under resource section of parent panel or UserControl and can be applied via StaticResource:
<Grid>
<Grid.Resources>
<ControlTemplate x:Key="MyTemplate"
TargetType="ButtonBase">
.......
</Grid.Resources>
<Button Name="register" Template="{StaticResource MyTemplate}"...>
</Grid>
Edit: As Rohit pointed out in the comments,
This won't work on Windows 8 because of some changes in PresentationFramework where default template of button is declared. ... In Windows 7 default template of button doesn't have that ControlTemplate trigger. That's why your posted code works fine on Windows7 but it won't work on Windows 8 and higher.
Rohit's answer about DependencyProperty Precedence being the cause is correct, but there's a much simpler way of fixing it than overwriting the Button's Template.
If you review the DependencyProperty Precedence List, you'll notice that properties set in the <Tag> have a higher precedence than Triggered properties, which is why your button will always use the background you have defined in your <Button> tag.
If you move the Background property to the <Style> itself, then triggered property will work since Triggered properties take precedence over properties defined in a Style.
<Button Name="register" Content="Register" ...>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="#FF0090D6" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
You have to override the default template for achieve this.
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="50" Height="50" HorizontalContentAlignment="Left" BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Hope this helps.
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="50" Height="50" HorizontalContentAlignment="Left" BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Above code perfectly works,
Even with this user can change the background color of button in runtime/codebehind

Change the Button contents in XAML on trigger

I'm trying to make a template that will change a Button's background as well as the color of it's TextBlock. I tried the following XAML in my template, but it just makes the button dissapear on mouseover. Is there any way to change the properties of a buttons contents on triggers?
<ControlTemplate TargetType="{x:Type Button}">
<Border
x:Name="Border"
CornerRadius="0"
BorderThickness="0"
Background="{x:Null}"
BorderBrush="#FF404040" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="White" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="TextBlock">
<TextBlock Foreground="Blue" />
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
Style:
<Style TargetType="{x:Type Button}" x:Key="MyButton">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border"
CornerRadius="0"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
TextBlock.Foreground="{TemplateBinding Foreground}"
BorderBrush="#FF404040">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="White" />
<Setter TargetName="Border" Property="TextBlock.Foreground" Value="Blue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage:
<Button Width="100" Height="50" Content="Lalala" Style="{StaticResource MyButton}" Background="Brown" Foreground="Green" BorderThickness="2"></Button>
You're missing the ContentPresenter, responsible for visualizing the Content property of the Button.
To set the foreground you can use TextBlock.Foreground attached property.
Control Styles and Templates has always been very usefull to me :)

Categories