WPF replacement options for an animated gif or How to make a spinner?
Option 1 – Spin an image using a Storyboard
UPDATE: Check out this more recent post: A SpinningImage control in WPF
If your animation is just a single image that moves, such as a spinner, you can use a Storyboard to spin the single image.
Here is a spinner.png file (128×128) that I made really quickly in Paint.NET.
- Create a default WPF Application project in visual studio.
- Add the spinner.png image to the project (or use your own image).
- Add a Storyboard to the resources.
Here is the Xaml.
<Window x:Class="SpinAnImage.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="300">
<Window.Resources>
<Storyboard x:Key="Spin360" Storyboard.TargetName="Spinner" Storyboard.TargetProperty="RenderTransform.(RotateTransform.Angle)">
<DoubleAnimation From="0" To="360" BeginTime="0:0:0" Duration="0:0:2" RepeatBehavior="Forever" />
</Storyboard>
</Window.Resources>
<Grid>
<Image Name="Spinner" Source="spinner.png" Width="128" Height="128" RenderTransformOrigin="0.5, 0.5">
<Image.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource Spin360}" />
</EventTrigger.Actions>
</EventTrigger>
</Image.Triggers>
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
</Image>
</Grid>
</Window>
Here is the simple Visual Studio 2010 project:
Option 2 – Loop through images using a Storyboard
This option is the one you would use if you have multiple images. You can create a Storyboard that loops through all of your images. If you have a gif, you can extract each image and use them.
Here is a BlackSpinner1.png file (128×128) that I made really quickly in Paint.NET. Actually I made eight versions of this image, where the section that is gray changes in each image.
Here is how you configure your project to animate through these images.
- Create a default WPF Application project in visual studio.
- Add a folder to the project called Images.
- Add the images you want to loop through to the Images directory.
- Add a Storyboard to the resources.
Here is the Xaml.
<Window x:Class="SpinUsingMultipleImages.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Spinner using multiple images" Height="300" Width="300">
<Grid>
<Grid.Resources>
<Storyboard x:Key="BlackSpinnerStoryBoard">
<ObjectAnimationUsingKeyFrames Duration="0:0:2" Storyboard.TargetProperty="Source" RepeatBehavior="Forever">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/BlackSpinner1.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.25">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/BlackSpinner2.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.50">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/BlackSpinner3.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.75">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/BlackSpinner4.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/BlackSpinner5.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:1.25">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/BlackSpinner6.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:1.50">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/BlackSpinner7.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:1.75">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/BlackSpinner8.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Image Name="BlackSpinner">
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource BlackSpinnerStoryBoard}" />
</EventTrigger.Actions>
</EventTrigger>
</Image.Triggers>
</Image>
</Grid>
</Window>
Here is a sample project attached.



Great solution. Only problem I had was the gif I used had 30 frames and each frame only contained the bit that differed from the previous frame. Used paint.net to layer and save each complete png. Took a while but the result is exactly what I was after and really so easy to implement. Thank you.
Your welcome. 🙂
Nice solution!
[…] single best demonstration I found was at WPFSharp. It’s all-XAML, intuitive, and complete (which is very helpful for […]