wpf storyboard for Chronometer - wpf

i have a textblock that displays second from 60 to 1 and it's foreground animate from green to red:
my xaml is like bellow and work fine:
<TextBlock x:Name="timer_check_version" Text="60" HorizontalAlignment="Center" FontSize="18">
<TextBlock.Foreground>
<SolidColorBrush x:Name="tbBrush" Color="#1e7145"/>
</TextBlock.Foreground>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource ChronometerStoryboard}"/>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
and my ChronometerStoryboard is:
<Storyboard x:Key="ChronometerStoryboard">
<ColorAnimation To="#b91d47" From="#1e7145"
Duration="0:0:59"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"/>
<StringAnimationUsingKeyFrames Storyboard.TargetProperty="(TextBlock.Text)">
<DiscreteStringKeyFrame KeyTime="0:0:1" Value="59"/>
<DiscreteStringKeyFrame KeyTime="0:0:2" Value="58"/>
<DiscreteStringKeyFrame KeyTime="0:0:3" Value="57"/>
<DiscreteStringKeyFrame KeyTime="0:0:4" Value="56"/>
<DiscreteStringKeyFrame KeyTime="0:0:5" Value="55"/>
<DiscreteStringKeyFrame KeyTime="0:0:6" Value="54"/>
<DiscreteStringKeyFrame KeyTime="0:0:7" Value="53"/>
<DiscreteStringKeyFrame KeyTime="0:0:8" Value="52"/>
<DiscreteStringKeyFrame KeyTime="0:0:9" Value="51"/>
<DiscreteStringKeyFrame KeyTime="0:0:10" Value="50"/>
......
......
......
......
<DiscreteStringKeyFrame KeyTime="0:0:51" Value="09"/>
<DiscreteStringKeyFrame KeyTime="0:0:52" Value="08"/>
<DiscreteStringKeyFrame KeyTime="0:0:53" Value="07"/>
<DiscreteStringKeyFrame KeyTime="0:0:54" Value="06"/>
<DiscreteStringKeyFrame KeyTime="0:0:55" Value="05"/>
<DiscreteStringKeyFrame KeyTime="0:0:56" Value="04"/>
<DiscreteStringKeyFrame KeyTime="0:0:57" Value="03"/>
<DiscreteStringKeyFrame KeyTime="0:0:58" Value="02"/>
<DiscreteStringKeyFrame KeyTime="0:0:59" Value="01"/>
</StringAnimationUsingKeyFrames>
</Storyboard>
the goal of above sample is to display a message to users for 60 seconds with TextBlock that counting down from 60 to 1,after 60 seconds the message and timer should be invisible and after some times according to background Threads the display of message and timer(TextBlock that counting down from 60 to 1) should be repeat,this may repeat for some times, all things work fine for first,but first the timer comes to 1,my message and timer collapsed for some minute(according to background threads) and when background threads completed i want to repeat the display of message and timer for 60 second again,but my problem is the timer value equals to 1 and timer Foreground equals to Red and no animated.

Apply AutoReverse and RepeatBeahvior attributes.
AutoReverse will make your storyboard goes exact reverse making your text color changing from Red to Green, and RepeatBehavior will make this to and fro color change continuing forever.
You can choose various RepeatBehavior settings according to your need.
<Storyboard x:Key="ChronometerStoryboard" AutoReverse="True" RepeatBehavior="Forever">
In reply to your comment :
"the visible and invisible of textblock may repeate forever and to time of invisible is random and after each visible it must start from 59 to 1 and it's foreground must start from green to red"
Use a Behavior called ControlStoryBoardAction which is present in Blend. And use it to play your storyboard.
Complete sample code might look like :
<UserControl
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:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
mc:Ignorable="d"
x:Class="S32494473W.Chronometer"
x:Name="UserControl"
d:DesignWidth="632" d:DesignHeight="392">
<UserControl.Resources>
<Storyboard x:Key="ChronometerStoryboard">
<ColorAnimation To="#b91d47" From="#1e7145"
Duration="0:0:10"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="timer_check_version"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TextBlock.Visibility)" Storyboard.TargetName="timer_check_version">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<StringAnimationUsingKeyFrames Storyboard.TargetProperty="(TextBlock.Text)" Storyboard.TargetName="timer_check_version">
<DiscreteStringKeyFrame KeyTime="0:0:1" Value="10"/>
<DiscreteStringKeyFrame KeyTime="0:0:2" Value="9"/>
<DiscreteStringKeyFrame KeyTime="0:0:3" Value="8"/>
<DiscreteStringKeyFrame KeyTime="0:0:4" Value="7"/>
<DiscreteStringKeyFrame KeyTime="0:0:5" Value="6"/>
<DiscreteStringKeyFrame KeyTime="0:0:6" Value="5"/>
<DiscreteStringKeyFrame KeyTime="0:0:7" Value="4"/>
<DiscreteStringKeyFrame KeyTime="0:0:8" Value="3"/>
<DiscreteStringKeyFrame KeyTime="0:0:9" Value="2"/>
<DiscreteStringKeyFrame KeyTime="0:0:10" Value="1"/>
</StringAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TextBlock.Visibility)" Storyboard.TargetName="timer_check_version">
<DiscreteObjectKeyFrame KeyTime="0:0:10" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<Button Content="Chronometer" Height="32" Margin="272,8,272,0" VerticalAlignment="Top" Click="Button_Click">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:ControlStoryboardAction Storyboard="{StaticResource ChronometerStoryboard}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<TextBlock x:Name="timer_check_version" Width="100" Background="AliceBlue" Text="10" Visibility="Hidden" HorizontalAlignment="Center" FontSize="18" VerticalAlignment="Center">
<TextBlock.Foreground>
<SolidColorBrush x:Name="tbBrush" Color="#1e7145"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</UserControl>

i change my trigger to :
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource ChronometerStoryboard}" Name="st1"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="st1"/>
</Trigger.ExitActions>
</Trigger>
and bind TextBlock.IsEnabled to it's Parent.Visibility and solved my problem.

Related

WPF Animate different control after first animation is over

I'm animating text in StatusBarItem (from right to left and then Opacity two times).
When this animation finishes It would like to show a button which is in a different StatusBarItem and is set to Visibility.Hidden by default.
How can I do this in XAML?
My XAML - error is "A storyboard tree in a Style cannot specify a TargetName":
<StatusBarItem x:Name="Stat_info" DockPanel.Dock="Right" FontStyle="Italic" Height="23" Foreground="#FFB41414" FontWeight="Bold" Visibility="Hidden">
<StatusBarItem.Style>
<Style TargetType="{x:Type StatusBarItem}">
<Style.Resources>
<Storyboard x:Key="flashAnimate">
<StringAnimationUsingKeyFrames Storyboard.TargetProperty="Content" >
<DiscreteStringKeyFrame Value="T" KeyTime="0:0:0.3" />
<DiscreteStringKeyFrame Value="Te" KeyTime="0:0:0.6" />
<DiscreteStringKeyFrame Value="Tes" KeyTime="0:0:0.9" />
<DiscreteStringKeyFrame Value="Test" KeyTime="0:0:1.2" />
</StringAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" AutoReverse="True" BeginTime="0:0:1.4" Duration="0:0:2.0" RepeatBehavior="0:0:5.4" />
<!--This is a button that should be set to visible-->
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Btn_info" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:5.5" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Style.Resources>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName= Stat_info, Path= IsVisible}" Value="True">
<Setter Property="Visibility" Value="Visible" />
<DataTrigger.EnterActions>
<BeginStoryboard Name="flash" Storyboard="{StaticResource flashAnimate}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="flash"/>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</StatusBarItem.Style>
</StatusBarItem>
EDIT:
I've tried provided answer from link, but I can't get It to work. I tried with & without TargetName and just for first animation. Result is no error & no animation :
<Window.Resources>
<ControlTemplate x:Key="StatusBarItemControlTemplate1" TargetType="{x:Type StatusBarItem}">
<ControlTemplate.Resources>
<Storyboard x:Key="myAnimation" Storyboard.TargetName="Stat_info">
<StringAnimationUsingKeyFrames Storyboard.TargetProperty="Content" >
<DiscreteStringKeyFrame Value="T" KeyTime="0:0:0.3" />
<DiscreteStringKeyFrame Value="Te" KeyTime="0:0:0.6" />
<DiscreteStringKeyFrame Value="Tes" KeyTime="0:0:0.9" />
<DiscreteStringKeyFrame Value="Test" KeyTime="0:0:1.2" />
</StringAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Stat_info" From="1" To="0" AutoReverse="True" BeginTime="0:0:1.4" Duration="0:0:2.0" RepeatBehavior="0:0:5.4" />
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding ElementName= Stat_info, Path= IsVisible}" Value="True">
<Setter Property="Visibility" Value="Visible" />
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="beginAnimation" Storyboard="{StaticResource myAnimation}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="beginAnimation" />
</DataTrigger.ExitActions>
</DataTrigger>
</ControlTemplate.Triggers>
<!-- Content to be animated goes here -->
</ControlTemplate>
</Window.Resources>
<StatusBarItem x:Name="Stat_info" Visibility="Hidden" Template="{StaticResource StatusBarItemControlTemplate1}" >

WPF MVVM: Triggering marching dot animation from value change

I'm trying to create a marching dot animation where there's a series of small circles and one will grow a bit and change color, then the next will, and so on, and this will bounce back and forth. The animation will be triggered by a bool value in the ViewModel.
I actually had this working before deciding to use the MVVM pattern, it was easy: I had the storyboard in the Page.Resources tags and called the animation from code behind on button click. Now I'm stuck with this decoupled, it seems no matter what I try there's always an error of some kind.
Here's the dots in xaml:
<Grid Grid.Row="4" Grid.Column="3" Grid.ColumnSpan="2" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Ellipse Name="Dot5" Grid.Row="1" Grid.Column="0" Style="{StaticResource ConnectionMeterOff}"/>
<Ellipse Name="Dot4" Grid.Row="1" Grid.Column="1" Style="{StaticResource ConnectionMeterOff}"/>
<Ellipse Name="Dot3" Grid.Row="1" Grid.Column="2" Style="{StaticResource ConnectionMeterOff}"/>
<Ellipse Name="Dot2" Grid.Row="1" Grid.Column="3" Style="{StaticResource ConnectionMeterOff}"/>
<Ellipse Name="Dot1" Grid.Row="1" Grid.Column="4" Style="{StaticResource ConnectionMeterOff}"/>
</Grid>
And my current animation:
<DataTemplate x:Key="MarchingDots">
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsConnecting}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard Name="MarchingDotsAnimation">
<Storyboard RepeatBehavior="Forever" AutoReverse="True">
<DoubleAnimation Storyboard.TargetName="Dot1" BeginTime="0:0:0.1"
Storyboard.TargetProperty="Width" From="10" To="15"
Duration="0:0:0.2" AutoReverse="True"/>
<ColorAnimation Storyboard.TargetName="Dot1" BeginTime="0:0:0.1"
Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
From="#FF5B5B5B" To="#FF84161C" Duration="0:0:0.3" AutoReverse="True"/>
<DoubleAnimation Storyboard.TargetName="Dot2" BeginTime="0:0:0.2"
Storyboard.TargetProperty="Width" From="10" To="15"
Duration="0:0:0.2" AutoReverse="True"/>
<ColorAnimation Storyboard.TargetName="Dot2" BeginTime="0:0:0.2"
Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
From="#FF5B5B5B" To="#FF84161C" Duration="0:0:0.3" AutoReverse="True"/>
<DoubleAnimation Storyboard.TargetName="Dot3" BeginTime="0:0:0.3"
Storyboard.TargetProperty="Width" From="10" To="15"
Duration="0:0:0.2" AutoReverse="True"/>
<ColorAnimation Storyboard.TargetName="Dot3" BeginTime="0:0:0.3"
Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
From="#FF5B5B5B" To="#FF84161C" Duration="0:0:0.3" AutoReverse="True"/>
<DoubleAnimation Storyboard.TargetName="Dot4" BeginTime="0:0:0.4"
Storyboard.TargetProperty="Width" From="10" To="15"
Duration="0:0:0.2" AutoReverse="True"/>
<ColorAnimation Storyboard.TargetName="Dot4" BeginTime="0:0:0.4"
Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
From="#FF5B5B5B" To="#FF84161C" Duration="0:0:0.3" AutoReverse="True"/>
<DoubleAnimation Storyboard.TargetName="Dot5" BeginTime="0:0:0.5"
Storyboard.TargetProperty="Width" From="10" To="15"
Duration="0:0:0.2" AutoReverse="True"/>
<ColorAnimation Storyboard.TargetName="Dot5" BeginTime="0:0:0.5"
Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
From="#FF5B5B5B" To="#FF84161C" Duration="0:0:0.3" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
I'm pretty sure my issue isn't the binding, but either that the animation isn't attached to the dots, or how I'm trying to wrap it to get access to the triggers. If I keep it just a Storyboard like before, I don't have anything to trigger it. If I try a style, it complains that I can use "Storyboard.TargetName". I've also tried EventTriggers. And copious amounts of Googling...all the examples seem to be single elements (like a rectangle) where the storyboard can be attached to the element's style.
I'm sure this is simple, but what am I doing wrong?
This needs a bit of cleanup, but it will get you started. First declare your animations:
<Storyboard x:Key="Storyboard1" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.25" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.25" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Storyboard2" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.25" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.75" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.25" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.75" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Storyboard3" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.75" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.75" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Storyboard4" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.75" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.25" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.75" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.25" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Storyboard5" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.25" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.25" Value="1.15"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
I'm going to build it out of ellipses, so create a base style for them:
<Style x:Key="EllipseStyle" TargetType="Ellipse">
<Setter Property="Fill" Value="Black" />
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="32" />
<Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
<Setter Property="Margin" Value="10" />
<Setter Property="RenderTransform">
<Setter.Value>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
Then create five ellipses, assign each one it's corresponding storyboard and use a DataTrigger to turn the animation on and off:
<UniformGrid Columns="5">
<Ellipse>
<Ellipse.Style>
<Style TargetType="Ellipse" BasedOn="{StaticResource EllipseStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Animating}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="Storyboard1" Storyboard="{StaticResource Storyboard1}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard1" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<Ellipse>
<Ellipse.Style>
<Style TargetType="Ellipse" BasedOn="{StaticResource EllipseStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Animating}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="Storyboard2" Storyboard="{StaticResource Storyboard2}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard2" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<Ellipse>
<Ellipse.Style>
<Style TargetType="Ellipse" BasedOn="{StaticResource EllipseStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Animating}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="Storyboard3" Storyboard="{StaticResource Storyboard3}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard3" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<Ellipse>
<Ellipse.Style>
<Style TargetType="Ellipse" BasedOn="{StaticResource EllipseStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Animating}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="Storyboard4" Storyboard="{StaticResource Storyboard4}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard4" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<Ellipse>
<Ellipse.Style>
<Style TargetType="Ellipse" BasedOn="{StaticResource EllipseStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Animating}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="Storyboard5" Storyboard="{StaticResource Storyboard5}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard5" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</UniformGrid>
<CheckBox Content="Animate" IsChecked="{Binding Animating}" HorizontalAlignment="Center"/>
</StackPanel>
I'm assuming there's a property in your view model called Animating that you're using to control this, I've added a checkbox to this code as well for testing:
EDIT: just updated the animations to get rid of that flicker on the right.

WPF - ToggleButton Template Trigger stop firing after first call

I have custom template for ToggleButton with triggers targeted for providing clear visual difference between Checked and Unchecked state.
Main concept:
Trigger 1. When Togglebuton is Unchecked and MouseOver = false: FontSize should be 13, FontWeight - Normal.
Trigger 2. When Togglebuton is Unchecked and MouseOver = true: FontSize should be 14, FontWeight - Normal.
Trigger 3. When Togglebuton is Checked: FontSize should be 15, FontWeight - Bold.
Everything is working fine, but after first toggleButton check/uncheck sequence
trigger 2 stops to fire and ToggleButton does not change appearence on MouseOver = true any more.
Here is my actual XAML.
<Style TargetType="{x:Type ToggleButton}" x:Key="DefaultToggleButtonStyle">
<Style.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2"
SnapsToDevicePixels="true"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
StrokeThickness="1"
StrokeDashArray="1 2" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
<Setter Property="Background" Value="{DynamicResource ButtonColor}" />
<Setter Property="Foreground" Value="{DynamicResource EditAreaColor}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="1" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="FontSize" Value="13" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<ControlTemplate.Resources>
<Style TargetType="Border" x:Key="MainBorderStyle">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="CornerRadius" Value="1" />
<Setter Property="UseLayoutRounding" Value="True" />
</Style>
</ControlTemplate.Resources>
<Grid>
<Border Background="Black" Opacity="0.5">
<Border.Effect>
<BlurEffect Radius="7" />
</Border.Effect>
</Border>
<Border x:Name="upperSurfaceBorder" Background="{TemplateBinding Background}" Style="{StaticResource MainBorderStyle}">
<Border x:Name="mouserOverHl" Background="Transparent"
Style="{StaticResource MainBorderStyle}"
BorderThickness="0.5" BorderBrush="{StaticResource MainNormal}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</Border>
<Border Background="Transparent" Style="{StaticResource MainBorderStyle}" x:Name="disabledOverlay" />
</Grid>
<ControlTemplate.Triggers>
<!--MouseOver-->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsChecked" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard>
<Storyboard TargetProperty="FontSize">
<DoubleAnimation To="14" Duration="0:0:.3">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<BeginStoryboard>
<Storyboard TargetProperty="FontSize">
<DoubleAnimation To="13" Duration="0:0:.3">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</MultiTrigger.ExitActions>
</MultiTrigger>
<!--IsChecked-->
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Trigger.Setters>
<Setter Property="Background" Value="{StaticResource MainVeryDark}"/>
</Trigger.Setters>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="FontWeight">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<FontWeight>Bold</FontWeight>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard TargetProperty="(ToggleButton.Background).(SolidColorBrush.Color)">
<ColorAnimation Duration="0:0:0.1" To="#002f67">
<ColorAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</ColorAnimation.EasingFunction>
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard TargetProperty="FontSize">
<DoubleAnimation To="15" Duration="0:0:0">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="FontWeight">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<FontWeight>Normal</FontWeight>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard TargetProperty="FontSize">
<DoubleAnimation To="13" Duration="0:0:0">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<!--Pressed-->
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard TargetName="upperSurfaceBorder" TargetProperty="Margin">
<ThicknessAnimation Duration="0:0:0.1" To="2 2 -2 -2">
<ThicknessAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard TargetName="upperSurfaceBorder"
TargetProperty="Margin">
<ThicknessAnimation Duration="0:0:0.1"
To="0 0 0 0">
<ThicknessAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<!--Disabled-->
<Trigger Property="IsEnabled" Value="False">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.3" Storyboard.TargetName="disabledOverlay"
Storyboard.TargetProperty="Background.Color" To="#55FFFFFF">
<ColorAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</ColorAnimation.EasingFunction>
</ColorAnimation>
<DoubleAnimation Duration="0:0:0.3" Storyboard.TargetProperty="Foreground.Opacity" To="0.6" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.3" To="Transparent" Storyboard.TargetName="disabledOverlay" Storyboard.TargetProperty="Background.Color">
<ColorAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut" />
</ColorAnimation.EasingFunction>
</ColorAnimation>
<DoubleAnimation Duration="0:0:0.3" Storyboard.TargetProperty="Foreground.Opacity" To="1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
<Setter Property="Visibility" Value="Visible" TargetName="disabledOverlay" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Any suggestions what's wrong?
Thanks in advance!
Your Main problem is in Trigger 3. I think EnterActions and ExitActions have not feeling good with IsChecked Property. I don't know why.
you must take another way to writing this trigger.
Well, as RezaNoei suggested, the problem was in ExitActions of Trigger 3. I solved this issue by removing of "To" property of font's size animation. This decision was inspired by this topic.

Can I set a different property at the end of a Storyboard/Animation in WPF?

I want to make an image flash a set number of times, when I set its Visibility to Visible. And when it's finished flashing, I want it to make itself Collapsed again.
Here's a simple version of what I'm trying to do:
<Image Visibility="Collapsed"
Margin="0,0,3,0"
Width="24"
Source="blah"
Height="24">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<Trigger Property="Visibility"
Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard RepeatBehavior="5x"
x:Name="flashingStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity"
Duration="0:0:1"
FillBehavior="Stop">
<DiscreteDoubleKeyFrame Value="0"
KeyTime="0:0:0" />
<DiscreteDoubleKeyFrame Value="1"
KeyTime="0:0:0.5" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
Can I do this in XAML?
If you know how many times it will be flashed then you can set BeginTime correspondingly the number of times your flashing comes along.
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames RepeatBehavior="5x" Storyboard.TargetProperty="Opacity" Duration="0:0:1">
<DiscreteDoubleKeyFrame Value="0" KeyTime="0:0:0" />
<DiscreteDoubleKeyFrame Value="1" KeyTime="0:0:0.5" />
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="0:0:5" Duration="0:0:0" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>

Button Animation Issue

I asked a previous question about adding a TabItem and I was told that using Buttons would be better and just animation to them. So I went ahead today and researched about this but I have come to an issue.
This is the XAML I have:
<Button Height="43" HorizontalAlignment="Left" IsEnabled="True" IsHitTestVisible="True" Margin="363,309,0,519" Name="home_btn" VerticalAlignment="Stretch" Width="346" >
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image Name="Normal" Source="Images/Normal1.png" />
<Image Name="Hover" Source="Images/Hover1.png" Opacity="0"/>
<Image Name="Pressed" Source="Images/view3.png" Opacity="0" Width="346" />
</Grid>
<ControlTemplate.Resources>
<Storyboard x:Key="MouseDownTimeLine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Pressed" Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="Pressed" Storyboard.TargetProperty="Width" From="274" To="300" Duration="00:00:00">
</DoubleAnimation>
</Storyboard>
<Storyboard x:Key="MouseUpTimeLine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Pressed" Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="MouseEnterTimeLine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Hover" Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="00:00:00.00" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="MouseExitTimeLine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Normal" Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="00:00:00.00" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="ButtonBase.IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource MouseDownTimeLine}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource MouseUpTimeLine}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource MouseEnterTimeLine}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource MouseExitTimeLine}"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
From this when I hover over my First image it will trigger the second image. The difference between these two is just the color, so it's not the problem.
When I click the button I want an arrow to appear next to the box (so i need the canvas to grow bigger) I created my Images in Photoshop and the third image I made bigger but it doesn't work, this is what happens.
As you can see from the second picture I want to aligned from the left and come out at the right. I have tried HorizontalAlignment="Left" and this doesn't work.

Resources