WPF set border background in trigger - wpf

I need to create a trigger, that will change Border background property, when MouseEnter occurred. I did the follow:
<Border Width="20" Height="30" Focusable="True">
<Border.Background>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Color="Aquamarine" Offset="0"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Color="Aquamarine" Offset="0"/>
<GradientStop Color="Beige" Offset="0.2"/>
<GradientStop Color="Firebrick" Offset="0.5"/>
<GradientStop Color="DarkMagenta" Offset="0.9"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
but it doesn't work. Thanks.

Common mistake. You have set the Border.Background property directly which will always override the value set by your trigger. (Locally set values have a very high precedence, style has a pretty low precedence.)
Instead, you should move your "normal" background into the Style like so:
<Border>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Color="Aquamarine" Offset="0"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Style.Triggers>
<!-- the trigger you showed -->
</Style.Triggers>
</Style>
</Border.Style>
</Border>

Related

WPF Effects on Button Text

I try to add a glow effect in the text of my buttons in my App.xaml but I can not find any Information on how to do it. All the effects I find are applied to the complete button.
Here is my code:
<Application x:Class="RSPolar.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="Button">
<Setter Property="FontSize" Value="48">
</Setter>
<Setter Property="Foreground" Value="#00EE00">
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Gray" Offset="1"/>
<GradientStop Color="DarkGray" Offset="0.52"/>
<GradientStop Color="Gray" Offset="0.5"/>
<GradientStop Color="LightGray" Offset="0.48"/>
<GradientStop Color="WhiteSmoke" Offset="0"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Color="Black" Direction="320" ShadowDepth="3" BlurRadius="10" Opacity="0.5" />
</Setter.Value>
</Setter>
<Setter Property="Button.Effect">
<Setter.Value>
<BlurEffect Radius="1"></BlurEffect>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
Try adding Textblock with Effect in Button as content.
<Window.Resources>
<Style TargetType="Button">
<Setter Property="FontSize" Value="48">
</Setter>
<Setter Property="Foreground" Value="#00EE00">
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Gray" Offset="1"/>
<GradientStop Color="DarkGray" Offset="0.52"/>
<GradientStop Color="Gray" Offset="0.5"/>
<GradientStop Color="LightGray" Offset="0.48"/>
<GradientStop Color="WhiteSmoke" Offset="0"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Color="Black" Direction="320" ShadowDepth="3" BlurRadius="10" Opacity="0.5" />
</Setter.Value>
</Setter>
<Setter Property="Button.Effect">
<Setter.Value>
<BlurEffect Radius="1"></BlurEffect>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Button Width="300" Height="200">
<TextBlock Text="Content">
<TextBlock.Effect>
<DropShadowEffect BlurRadius="8" Color="#00EE00" ShadowDepth="0"/>
</TextBlock.Effect>
</TextBlock>
</Button>
Update
Using ContentTemplate in style you can use it for all button.
<Window.Resources>
<Style TargetType="Button">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock FontSize="48" Foreground="#00EE00" Text="{Binding Path=Content,RelativeSource={RelativeSource AncestorType={x:Type Button}}}">
<TextBlock.Effect>
<DropShadowEffect BlurRadius="8" Color="#00EE00" ShadowDepth="0"/>
</TextBlock.Effect>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Gray" Offset="1"/>
<GradientStop Color="DarkGray" Offset="0.52"/>
<GradientStop Color="Gray" Offset="0.5"/>
<GradientStop Color="LightGray" Offset="0.48"/>
<GradientStop Color="WhiteSmoke" Offset="0"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Color="Black" Direction="320" ShadowDepth="3" BlurRadius="10" Opacity="0.5" />
</Setter.Value>
</Setter>
<Setter Property="Button.Effect">
<Setter.Value>
<BlurEffect Radius="1"></BlurEffect>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Width="300" Content="content1" Height="200"/>
<Button Width="300" Content="content2" Margin="0,10,0,0" Height="200"/>
</StackPanel>

Applying same style to multiple elements

I am new to using WPF and I was trying to apply Style (e.g. Background for TextBox, Button and MenuItem should be Orange). To achieve this I did something like:
<Style TargetType="TextBox" x:Key="sampleTextBox">
<Setter Property="Margin" Value="2"/>
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="FontSize" Value="11px"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
<GradientStop Color="#FFFFD190" Offset="0.2"/>
<GradientStop Color="Orange" Offset="0.85"/>
<GradientStop Color="#FFFFD190" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
and repeated the same piece of code for targettype Button and for target menu.
This is working absolutely fine. But I would like to minimize the amount of repeated code by probably having multiple targettype values.
Please let me know if it is possible.
Thanks.
<Window.Resources>
<Style x:Key="sampleTextBox">
<Setter Property="Control.FontFamily" Value="Verdana"/>
<Setter Property="Control.FontSize" Value="11px"/>
<Setter Property="Control.FontWeight" Value="Bold"/>
<Setter Property="Control.Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
<GradientStop Color="#FFFFD190" Offset="0.2"/>
<GradientStop Color="Orange" Offset="0.85"/>
<GradientStop Color="#FFFFD190" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock Text="This is a string and it should be wrapped." Style="{StaticResource sampleTextBox}"/>
<TextBox Text="This is a string and it should be wrapped." Style="{StaticResource sampleTextBox}"/>
</StackPanel>
Style has an attribute BasedOn. http://msdn.microsoft.com/en-us/library/system.windows.style.basedon.aspx With this you can use Style inheritance. Define a base style with common attributes and derive your child styles with specific attributes.
You could use FrameworkElement as a TargetType:
<Style TargetType="FrameworkElement" x:Key="CommonStyle">
<Setter Property="Control.Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
<GradientStop Color="#FFFFD190" Offset="0.2"/>
<GradientStop Color="Orange" Offset="0.85"/>
<GradientStop Color="#FFFFD190" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
And then use specific styles for each element by inheriting (BasedOn) CommonStyle:
<Style TergetType="TextBox" BasedOn="{StaticResource CommonStyle}" x:Key="TextBoxStyle">
<Setter Property="Margin" Value="2"/>
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="FontSize" Value="11px"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>

WPF/Styles: Setting Property Values of Template Elements

Suppose I have a style like
<Style x:Key="NotificationItemTemplate" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<DockPanel LastChildFill="False">
<DockPanel.Background>
<LinearGradientBrush>
<GradientStop Offset="0" Color="#FF565656" /> <!-- How to change color values -->
<GradientStop Offset="1" Color="#FF353535" />
</LinearGradientBrush>
</DockPanel.Background>
...
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I set the color value of a gradient stop as labeled above to a different color, say on MouseOver, I know I use a Trigger, but how do I refer to that color value?
Unfortunately, I'm not sure if you can do it for a single gradient stop. You likely have to trigger to change the entire background brush:
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<DockPanel LastChildFill="False" x:Name="dock">
<DockPanel.Background>
<LinearGradientBrush>
<GradientStop Offset="0" Color="#FF565656" />
<!-- How to change color values -->
<GradientStop Offset="1" Color="#FF353535" />
</LinearGradientBrush>
</DockPanel.Background>
<ContentPresenter />
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="dock" Property="Background">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0" Color="#00CDFFFF" />
<!-- How to change color values -->
<GradientStop Offset="1" Color="#FF343465" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Using Styles in Windows Presentation Foundation

Imagine I have a data bound ListView and in the <ControlTemplate.Triggers>
I have the following
<DataTrigger Binding="{Binding Path=Status}" Value="Completed">
<Setter Property="Background" Value="{StaticResource CompletedBackground}" />
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
I want that to be bound to a Style i have in my Grid.Resources which looks like the following:
<Style x:Key="CompletedBackground" TargetType="ListViewItem">
<Setter>
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFBCFAA6" Offset="0"/>
<GradientStop Color="#FFA3E88B" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
However, as you might imagine this doesn't work, suprise suprise, you can't bind "Setter" to "Background", so my question is, how do I actually solve the problem?
I've looked through the following a lot of times, cant find any information here.
What you're trying to do is fundamentally flawed. For starters, your style's setter doesn't specify a target property. Presumably, the target property should be Background:
<Style x:Key="CompletedBackground" TargetType="ListViewItem">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFBCFAA6" Offset="0"/>
<GradientStop Color="#FFA3E88B" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
Secondly, you're then trying to assign a Style instance to the Background property, which is of type Brush, not Style.
Depending on exactly what you're trying to achieve, you should be able to just change the Style to a Brush resource:
<LinearGradientBrush x:Key="CompletedBackground" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFBCFAA6" Offset="0"/>
<GradientStop Color="#FFA3E88B" Offset="1"/>
</LinearGradientBrush>
Then use it from your trigger in the same fashion you already are.

How to change control template from Style.Triggers

I've done it this way:
<Style x:Key="Button" BasedOn="{StaticResource LoginButton}" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border CornerRadius="4">
<Border.Background>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Offset="0" Color="#0863a5" />
<GradientStop Offset="1" Color="#00457d" />
</LinearGradientBrush>
</Border.Background>
</Border>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border CornerRadius="4">
<Border.Background>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Offset="0" Color="#508fbd" />
<GradientStop Offset="1" Color="#397ab0" />
</LinearGradientBrush>
</Border.Background>
</Border>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Is there any better way to do this? I've scenarios where my control template is having more lines of code, and I'd only require to change a single style like BorderBrush or something. How can I change control template from Style.Triggers efficiently?
If your intention is just to give a different Background to the Border. You can achieve this in the ControlTemplate.Triggers
<Style x:Key="Button" BasedOn="{StaticResource LoginButton}" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate >
<Grid>
<Border x:Name="brd" CornerRadius="4">
<Border.Background>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Offset="0" Color="#0863a5" />
<GradientStop Offset="1" Color="#00457d" />
</LinearGradientBrush>
</Border.Background>
</Border>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="brd">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Offset="0" Color="#508fbd" />
<GradientStop Offset="1" Color="#397ab0" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Resources