WPF: Hiding object causes brief flash before disappearing - wpf

I have a simple button style which has data trigger which binds to a bool property and if property is false it hides the button using simple fade out animation and vice-versa.
But for some unknown reason, for the first time when I perform some task which sets the bool value to false. It gives a brief flash before fading out. Upon setting it to true everything is as expected.
My style is
<Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}" >
<Style.Triggers>
<DataTrigger Binding="{Binding IsButtonVisible}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="Opacity" >
<DoubleAnimation Duration="0:0:0.2" To="1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="Opacity" >
<DoubleAnimation Duration="0:0:0.2" To="0"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<Trigger Property="Opacity" Value="0">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<Trigger Property="Opacity" Value="1" >
<Setter Property="Visibility" Value="Visible"></Setter>
</Trigger>
</Style.Triggers>
<Style.Setters>
<Setter Property="Height" Value="93"/>
<Setter Property="Width" Value="93"/>
<Setter Property="Opacity" Value="0"/>
</Style.Setters>
</Style>
Note:-
Default value of IsButtonVisible is true

Why do you have two DataTrigger? Try this solution, maybe it solves your problem.
<Style x:Key="DefaultButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard FillBehavior="HoldEnd" Storyboard.TargetProperty="Opacity">
<DoubleAnimation Duration="0:0:0.2" To="1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="Opacity" >
<DoubleAnimation Duration="0:0:0.2" To="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<Trigger Property="Opacity" Value="0">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<Trigger Property="Opacity" Value="1">
<Setter Property="Visibility" Value="Visible"></Setter>
</Trigger>
</Style.Triggers>
<Style.Setters>
<Setter Property="Height" Value="93"/>
<Setter Property="Width" Value="93"/>
<Setter Property="Opacity" Value="0"/>
</Style.Setters>
</Style>
Edit:
XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="279.716" Width="279.784"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
<Style x:Key="ButtonStyleTrue" TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding VisibleTrue}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard FillBehavior="HoldEnd" Storyboard.TargetProperty="Opacity">
<DoubleAnimation Duration="0:0:0.2" To="1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="Opacity" >
<DoubleAnimation Duration="0:0:0.2" To="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<Trigger Property="Opacity" Value="0">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<Trigger Property="Opacity" Value="1">
<Setter Property="Visibility" Value="Visible"></Setter>
</Trigger>
</Style.Triggers>
<Style.Setters>
<Setter Property="Height" Value="93"/>
<Setter Property="Width" Value="93"/>
<Setter Property="Opacity" Value="0"/>
</Style.Setters>
</Style>
<Style x:Key="ButtonStyleFalse" TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding VisibleFalse}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard FillBehavior="HoldEnd" Storyboard.TargetProperty="Opacity">
<DoubleAnimation Duration="0:0:0.2" To="1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="Opacity" >
<DoubleAnimation Duration="0:0:0.2" To="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<Trigger Property="Opacity" Value="0">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<Trigger Property="Opacity" Value="1">
<Setter Property="Visibility" Value="Visible"></Setter>
</Trigger>
</Style.Triggers>
<Style.Setters>
<Setter Property="Height" Value="93"/>
<Setter Property="Width" Value="93"/>
<Setter Property="Opacity" Value="0"/>
</Style.Setters>
</Style>
</Window.Resources>
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="187,11,0,0" VerticalAlignment="Top" Width="75" Click="Button_OnClick"/>
<Button Style="{StaticResource ButtonStyleFalse}" Content="Button" HorizontalAlignment="Left" Margin="47,66,0,0" VerticalAlignment="Top" Width="75"/>
<TextBlock x:Name="textBlock_true" HorizontalAlignment="Left" Margin="193,68,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
<Button Style="{StaticResource ButtonStyleTrue}" Content="Button" HorizontalAlignment="Left" Margin="47,143,0,0" VerticalAlignment="Top" Width="75"/>
<TextBlock x:Name="textBlock_false" HorizontalAlignment="Left" Margin="193,145,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
</Grid>
Code Behind
using System.ComponentModel;
using System.Windows;
namespace WpfApplication1
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
/// <summary>
/// Initalvalue is true;
/// </summary>
public bool VisibleTrue
{
get { return _VisibleTrue; }
set
{
if (_VisibleTrue == value) return;
_VisibleTrue = value;
textBlock_true.Text = value ? "True" : "False";
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("VisibleTrue"));
}
}
private bool _VisibleTrue = true;
/// <summary>
/// Initialvalue is false
/// </summary>
public bool VisibleFalse
{
get { return _VisibleFalse; }
set
{
if (_VisibleFalse == value) return;
_VisibleFalse = value;
textBlock_false.Text = value ? "True" : "False";
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("VisibleFalse"));
}
}
private bool _VisibleFalse;
public MainWindow()
{
InitializeComponent();
textBlock_true.Text = "Application started";
textBlock_false.Text = "Application started";
}
public event PropertyChangedEventHandler PropertyChanged;
private void Button_OnClick(object sender, RoutedEventArgs e)
{
VisibleTrue = !VisibleTrue;
VisibleFalse = !VisibleTrue;
}
}
}
Preview

To prevent setting your bound property IsButtonVisible while animation performs you could add the following to your ViewModel:
private bool _animationInProgress = false;
private readonly object _animationLock = new object();
private bool _isButtonVisible = true;
public bool IsButtonVisible {
get { return _isButtonVisible; }
set {
lock (_animationLock) {
if (value == _isButtonVisible || _animationInProgress) return;
_animationInProgress = true;
}
_isButtonVisible = value;
OnPropertyChanged();
Timer animationDoneTimer = new Timer {Interval = 200, Enabled = true, AutoReset = false};
animationDoneTimer.Elapsed += (sender, args) => {
lock (_animationLock) {
_animationInProgress = false;
}
};
}
}
As second thing I would remove the Trigger:
<Trigger Property="Opacity" Value="1" >
<Setter Property="Visibility" Value="Visible"></Setter>
</Trigger>
For the behaviour, that you'd like to set Visibility to Collapsed on Opacity == 0 and Visibility to Visible on Opacity =! 0 you should do it this way:
...
<Trigger Property="Opacity" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
<!-- Trigger removed -->
</Style.Triggers>
<Style.Setters>
<!-- Visibilities value if Trigger Opacity == 0 does not fire -->
<Setter Property="Visibility" Value="Visible" />
<Setter Property="Height" Value="93"/>
<Setter Property="Width" Value="93"/>
<Setter Property="Opacity" Value="0"/>
</Style.Setters>
</Style>

Related

Style triggers don't inherit?

I have a style with the following triggers defined:
<Style TargetType="{x:Type graphicElements:MyTabItem}" x:Key="StMyTabItemBase">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="SelectedColor" Value="{Binding ApplicationColor, RelativeSource={RelativeSource AncestorType=graphicElements:MyTabControl}}" />
<Setter Property="Expanded" Value="False" />
<Setter Property="BorderBrush" Value="#FFACACAC"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="SnapsToDevicePixels" Value="False" />
<Setter Property="Template" Value="{StaticResource CtTabCollapsed}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSideBarExpanded, RelativeSource={RelativeSource AncestorType=graphicElements:MyTabControl}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="Expanded" BeginTime="0" Duration="0">
<DiscreteBooleanKeyFrame Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="Expanded" BeginTime="0:0:0.25" Duration="0">
<DiscreteBooleanKeyFrame Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<Trigger Property="Expanded" Value="True">
<Setter Property="Template" Value="{StaticResource CtTabExpanded}" />
</Trigger>
</Style.Triggers>
</Style>
This works perfectly when I apply the direct style. However, I want to be able to create styles based on this style to override specific properties like margins and colors. I have tried to do so as follows (this creates a default based on this style):
<Style TargetType="{x:Type graphicElements:MyTabItem}" BasedOn="{StaticResource StMyTabItemBase}" />
However, as soon as I do that it no longer triggers or switches the template properly. If I copy just the triggers into the new style it works again, but I don't want to have to put the triggers into each style individually... Why aren't these inheriting like they are supposed to? Or do I misunderstand something about BasedOn and Triggers?
EDIT
Here is the 'BasedOn' style that works:
<Style TargetType="{x:Type graphicElements:AutodeskTabItem}" BasedOn="{StaticResource StAutodeskTabItemBase}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSideBarExpanded, RelativeSource={RelativeSource AncestorType=graphicElements:AutodeskTabControl}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="Expanded" BeginTime="0" Duration="0">
<DiscreteBooleanKeyFrame Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="Expanded" BeginTime="0:0:0.25" Duration="0">
<DiscreteBooleanKeyFrame Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<Trigger Property="Expanded" Value="True">
<Setter Property="Template" Value="{StaticResource CtTabExpanded}" />
</Trigger>
</Style.Triggers>
</Style>
Basically I just copied out the triggers portion of the base style. However I don't understand why I have to do that...
I'm not sure about "supposed to" but your exit storyboard definitely won't find the first.
I recently came across this behaviour. It's an oddity to do with namescope. That won't work.
You could try starting another storyboard targeting the same property with 0 duration and hope that stops it. This did not work in my case.
The way I work round this in my app is to use a multiconverter to start and stop the storyboard.
My converter:
public class MultiAnimatorConverter : MarkupExtension, IMultiValueConverter
{
public Storyboard sb { get; set; }
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// 0 = Shape
// 1 = Tag
Shape shape = values[0] as Shape;
if(shape.Tag.ToString() == "False")
{
sb.Stop(shape);
sb.Remove(shape);
}
else
{
sb.Begin(shape, true);
}
return true; // Abusing isenabled so I don't need another attached dependency property
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
You may prefer an attached property to enabled.
Useage:
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding Converter="{ui:MultiAnimatorConverter sb={StaticResource MarchinAntsAnimation}}">
<Binding RelativeSource="{RelativeSource Self}"/>
<Binding Path="Tag" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Setter.Value>
</Setter>
My storyboard is a separate resource.
Storyboard.TargetProperty="(Shape.StrokeDashOffset)"
RepeatBehavior="Forever"
From="0"
To="8"
Duration="00:00:.8"
Timeline.DesiredFrameRate="10"
/>
This is used in my Map Editor ( for our game ). The user is drawing the map for a scenario. They draw terrain. Woods, rivers, contours etc. All are polygons with different templates and I use basedon to inherit so all would get the same "marching ants" animation with dotted lines animated round them when the terrain is selected for editing.

WPF: Stop Animation For Hidden Controls on Windows Load

I have a very simple fade in/out animation which works fine using data triggers. I have bind the data trigger to a bool property and inside trigger it set the opacity to 0 on false and vice versa.
Now the problem is the objects whose bool value is false upon loading, I don't expect them to show on load and then animate themselves to hide.
I have tried to set the opacity to 0 on style setter but no use
Here is the button style
<Style x:Key="LocationPickerButtonStyle" TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="Height" Value="93"/>
<Setter Property="Width" Value="93"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid >
<Image x:Name="DefaultImage" Source="something.png"/>
<Ellipse x:Name="HitTest" Fill="Transparent" Height="93" Width="93" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsLocationVisible}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="showSelectedLocation">
<Storyboard Storyboard.TargetProperty="Opacity">
<DoubleAnimation Duration="0:0:1" From="0" To="1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="showSelectedLocation"></StopStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsLocationVisible}" Value="false">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="hideSelectedLocation">
<Storyboard Storyboard.TargetProperty="Opacity" >
<DoubleAnimation Duration="0:0:1" From="1" To="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="hideSelectedLocation"></StopStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<Trigger Property="Opacity" Value="0">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<Trigger Property="Opacity" Value="1">
<Setter Property="Visibility" Value="Visible"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
Do these changes in your XAML :
Shift your DataTriggers from <ControlTemplate.Triggers> to Style.Triggers.
Set Opacity = 0 in Style Setter as starting Opacity for every Button.
Remove From = 1 in false DataTrigger.
With all the changes, your Style would look like this :
<Style x:Key="LocationPickerButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsLocationVisible}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="showSelectedLocation">
<Storyboard Storyboard.TargetProperty="Opacity">
<DoubleAnimation Duration="0:0:1" From="0" To="1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="showSelectedLocation"></StopStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsLocationVisible}" Value="false">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="hideSelectedLocation">
<Storyboard Storyboard.TargetProperty="Opacity" >
<DoubleAnimation Duration="0:0:1" To="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="hideSelectedLocation"></StopStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
<Style.Setters>
<Setter Property="Height" Value="93"/>
<Setter Property="Width" Value="93"/>
<Setter Property="Opacity" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid >
<Image x:Name="DefaultImage" Source="something.png"/>
<Ellipse x:Name="HitTest" Fill="Transparent" Height="93" Width="93" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Opacity" Value="0">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<Trigger Property="Opacity" Value="1">
<Setter Property="Visibility" Value="Visible"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>

Change background of all the textblocks in a Page to Transparent by clicking on a textblock and change the background of clicked textblock to Blue

I have my problem half solved.
Look at the below code:
<Style TargetType="TextBlock">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseDown">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="Blue" Duration="0:0:0.100" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
As you can see in the above style, I can change the background of a clicked textblock to Blue. But I also want to change the background of other textblocks to Transparent.
It seems u want to change style of only selected textblock . You can use listbox for your requirement as listbox item is having style for selected and unselected item.
Maybe I am wrong..but try this.this is might be helpful.
I have used different color in style ..You can use own colors as per your requirement
<Style x:Key="listbox_Item" TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Border Margin="10" x:Name="BorderStyle" Background="Transparent" BorderBrush="Red" BorderThickness="1"/>
<ContentPresenter></ContentPresenter>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="false">
<Trigger.EnterActions>
<BeginStoryboard x:Name="unselectedAnimation">
<Storyboard >
<ColorAnimation Storyboard.TargetName="BorderStyle" Storyboard.TargetProperty="BorderBrush.Color" From="Transparent" To="Green" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="unselectedAnimation" />
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Trigger.EnterActions>
<BeginStoryboard x:Name="selectedAnimation">
<Storyboard>
<Storyboard >
<ColorAnimation Storyboard.TargetName="BorderStyle" Storyboard.TargetProperty="BorderBrush.Color" From="Transparent" To="Red" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="selectedAnimation"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground"
Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and behind code u need to create a class and itemsouce for listbox
InitializeComponent();
List<tileproperty> abc = new List<tileproperty>();
abc.Add(new tileproperty("ssss", "dssds"));
abc.Add(new tileproperty("ssss", "dssds"));
lst.ItemsSource = abc;
}
public class tileproperty
{
public string next { get; set; }
public string path { get; set; }
public tileproperty(string next, string path)
{
this.next = next;
this.path = path;
}
}

Extend the style to capture click event

I am trying to build a designer like visual studio.
Take a look at the xaml:
<Style x:Key="myStyle" TargetType="{x:Type Border}">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="2" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="DodgerBlue" />
</Trigger>
</Style.Triggers>
</Style>
...
...
...
<Border Style="myStyle">
<Grid>
<Border Style="myStyle">
<Rectangle Fill="Transparent" />
<TextBlock Text="abc" />
</Border>
</Grid>
</Border>
The above code is working perfectly. Now I want to extend the above style, such that the border's color should change to green when I click on any of the control.
Update :
I have changed the above style to something like below code.
<Style x:Key="BorderStyle" TargetType="{x:Type Border}">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="2" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="DodgerBlue" />
</Trigger>
<EventTrigger RoutedEvent="MouseDown">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="Green" Duration="0:0:0.100" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
Now I can see the border is changing its color to green when I click on it. But when mouse leaves the textblock, the border changes its color back to transparent.
<Style.Triggers>
<EventTrigger RoutedEvent="MouseDown">
<Setter Property="BorderBrush" Value="DodgerBlue" />
</EventTrigger>
</Style.Triggers>
and you dont want to bind the style for all the border, if you need to apply that style for all the border, just remove the key name of that style. It will apply to all the Targeted Control.
If you need to check and apply the color as like the button click as like a Toggle button, you need to maintain a property and that property is to be given in the trigger and it need to be changed in the button's click..
Try this
<Style x:Key="myStyle" TargetType="{x:Type Border}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush x:Name="BorderBrushColor" Color="Transparent"></SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="2" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="DodgerBlue" />
</Trigger>
<EventTrigger RoutedEvent="MouseDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="Green" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
Try this
<Style x:Key="myStyle" TargetType="{x:Type Border}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush x:Name="BorderBrushColor" Color="Transparent"></SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="2" />
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames FillBehavior="HoldEnd" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="DodgerBlue" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames FillBehavior="HoldEnd" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="Green" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
Add this code in previous style
<Trigger Property="IsMouseOver" Value="False">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames FillBehavior="HoldEnd" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="Transparent" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>

WPF Animation of DataGridRow Background color from transparent to "Current" (current is set with Trigger)

I'm setting DataGridRow BackgroundColor to Green or to Red with trigger based on LogError value.
I want to animate newly added rows with transparency.
This works fine:
From="Transparent" To="Red"
But what I want color to goes to is current color set with Style. Its not always Red it could be Green as well.
This does not work:
From="Transparent" To="{TemplateBinding DataGridRow.Background}"
or
From="Transparent" To="{Binding RelativeSource={RelativeSource Self}, Path=Backgound}"
Code:
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property = "Background" Value="LimeGreen"/>
<Style.Triggers>
<DataTrigger Binding="{Binding LogMessage}" Value="Exception has occured">
<Setter Property = "Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(DataGridRow.Background).(SolidColorBrush.Color)"
Duration="00:00:03"
From="Transparent"
To="{TemplateBinding DataGridRow.Background}"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
Error message: Cannot freeze this Storyboard timeline tree for use across threads.
There are few problems in your XAML code.
First, you have specified default style under resources section of DataGrid and later provide your own style which will override default style.
Either you should define new style and set its BasedOn DP to refer to default style. But in your case i don't see any use of defining separate style just for trigger.
Second, you want your animation to go from Transparent to colour selected in style which can either by LimeGreen or Red depending on trigger. So, you should not set To value in your animation since it will automatically picked up.
This will work as you desire -
<DataGrid>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property ="Background" Value="LimeGreen"/>
<Style.Triggers>
<DataTrigger Binding="{Binding LogMessage}"
Value="Exception has occured">
<Setter Property = "Background" Value="Red"/>
</DataTrigger>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty=
"(DataGridRow.Background).(SolidColorBrush.Color)"
Duration="00:00:03"
From="Transparent"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
</DataGrid>
#Den
You have to determinate a standart Color, before you animate. This is my Style for animating a row and cell.
<Style TargetType="{x:Type DataGridRow}">
<Style.Setters>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="Transparent"/>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#FFF37C21"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(DataGridRow.Background).(SolidColorBrush.Color)" Duration="00:00:0.2" To="#FFF37C21"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(DataGridRow.Background).(SolidColorBrush.Color)" Duration="00:00:0.2" To="Transparent"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Style.Setters>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="IsTabStop" Value="False" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid x:Name="gridCell" Background="#00FFFFFF">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<ContentPresenter
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.FontWeight)">
<DiscreteObjectKeyFrame KeyTime="00:00:0.2">
<DiscreteObjectKeyFrame.Value>
<FontWeight>Bold</FontWeight>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.FontWeight)">
<DiscreteObjectKeyFrame KeyTime="00:00:0.2">
<DiscreteObjectKeyFrame.Value>
<FontWeight>Light</FontWeight>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>

Resources