Contents

WPF: Starting and stopping animation on another control's property change

This example will start an animation when the mouse is over a button and stop the animation when the button is not over the button anymore.

1 Create project

Fire up Visual Studio and create new “WPF Application” project (name it “WPFStartingStoppingAnimationByPropertyChange”, for example):

./create-project.png
Create new WPF application

2 Add controls

Create a window with a button and a TextBlock:

./main-window.png
Main application window

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<Window x:Class="WPFStartingStoppingAnimationByPropertyChange.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"
        mc:Ignorable="d"
        Title="MainWindow" Height="240" Width="800">
	<Grid x:Name="GridMain">
		<Grid.ColumnDefinitions>
			<ColumnDefinition/>
			<ColumnDefinition/>
		</Grid.ColumnDefinitions>
		<Button x:Name="ButtonStartAnimation" Content="MouseOver"/>
		<TextBlock x:Name="TextBlockToAnimate"
				   HorizontalAlignment="Center"
				   TextWrapping="Wrap"
				   Text="TextBlock"
				   VerticalAlignment="Center"
				   FontSize="36" Grid.Column="1"/>
	</Grid>
</Window>

3 Add Storyboards and DataTriggers to TextBlock

Change Textblock code from

1
2
3
4
5
6
<TextBlock x:Name="TextBlockToAnimate"
		   HorizontalAlignment="Center"
		   TextWrapping="Wrap"
		   Text="TextBlock"
		   VerticalAlignment="Center"
		   FontSize="36" Grid.Column="1"/>

… to:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<TextBlock x:Name="TextBlockToAnimate"
		   HorizontalAlignment="Center"
		   TextWrapping="Wrap"
		   Text="TextBlock"
		   VerticalAlignment="Center"
		   FontSize="36" Grid.Column="1"> <!-- CAUTION: changes from "/>" to ">" -->
	<TextBlock.Style>
		<Style TargetType="{x:Type TextBlock}">
			<Style.Triggers>
				<DataTrigger Binding="{Binding ElementName=ButtonStartAnimation, Path=IsMouseOver}" Value="True">
					<!-- Begin Storyboard animate opacity -->
					<DataTrigger.EnterActions>
						<BeginStoryboard Name="MyBeginStoryboard">
							<Storyboard>
								<DoubleAnimation 
								 Storyboard.TargetProperty="(TextBlock.Opacity)"
								 From="1.0"
								 To="0.0"
								 Duration="0:0:1"
								 AutoReverse="True"
								 RepeatBehavior="Forever" />
							</Storyboard>
						</BeginStoryboard>
					</DataTrigger.EnterActions>
					<!-- Stop the Storyboard -->
					<DataTrigger.ExitActions>
						<StopStoryboard BeginStoryboardName="MyBeginStoryboard" />
					</DataTrigger.ExitActions>
				</DataTrigger>
			</Style.Triggers>
		</Style>
	</TextBlock.Style>
</TextBlock>

Result

The finished application:

./running-application.gif
Main application window

Full code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<Window x:Class="WPFStartingStoppingAnimationByPropertyChange.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"
        mc:Ignorable="d"
        Title="MainWindow" Height="240" Width="800">
	<Grid x:Name="GridMain">
		<Grid.ColumnDefinitions>
			<ColumnDefinition/>
			<ColumnDefinition/>
		</Grid.ColumnDefinitions>
		<Button x:Name="ButtonStartAnimation" Content="MouseOver"/>
		<TextBlock x:Name="TextBlockToAnimate"
				   HorizontalAlignment="Center"
				   TextWrapping="Wrap"
				   Text="TextBlock"
				   VerticalAlignment="Center"
				   FontSize="36" Grid.Column="1">  <!-- CAUTION: changes from "/>" to ">" -->
			<TextBlock.Style>
				<Style TargetType="{x:Type TextBlock}">
					<Style.Triggers>
						<DataTrigger Binding="{Binding ElementName=ButtonStartAnimation, Path=IsMouseOver}" Value="True">
							<!-- Begin Storyboard animate opacity -->
							<DataTrigger.EnterActions>
								<BeginStoryboard Name="MyBeginStoryboard">
									<Storyboard>
										<DoubleAnimation 
										 Storyboard.TargetProperty="(TextBlock.Opacity)"
										 From="1.0"
										 To="0.0"
										 Duration="0:0:1"
										 AutoReverse="True"
										 RepeatBehavior="Forever" />
									</Storyboard>
								</BeginStoryboard>
							</DataTrigger.EnterActions>
							<!-- Stop the Storyboard -->
							<DataTrigger.ExitActions>
								<StopStoryboard BeginStoryboardName="MyBeginStoryboard" />
							</DataTrigger.ExitActions>
						</DataTrigger>
					</Style.Triggers>
				</Style>
			</TextBlock.Style>
		</TextBlock>
	</Grid>
</Window>

Download sample project

  • Here you can download the sample project (built with Visual Studio 2022, .Net 6 - .zip, 4 KB).