A SpinningImage control in WPF

In the past, I once wrote an article about WPF replacement options for an animated gif.

I have added an example project on GitHub: WpfSharp.Controls

Recently I needed to use this again, but I wanted a control that was more MVVM friendly. I also didn’t want to have to add a bunch of XAML every time I used it. This might sound crazy, but I wanted a reusable object. (Crazy right? 😉 Anyway, this led me to create a custom control that inherits from Image called SpinningImage.

So here is what I wanted. An Image with a simple bool dependency property that makes the image spin when true and stop spinning when false.

I used both XAML and csharp for this:

<Image x:Class="WpfSharp.UserControls.SpinningImage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             Name="ImageInstance"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             RenderTransformOrigin="0.5, 0.5" >
    <Image.Resources>
        <Storyboard x:Key="Spin360" Storyboard.TargetName="ImageInstance" Storyboard.TargetProperty="RenderTransform.(RotateTransform.Angle)">
            <DoubleAnimation From="0" To="360" BeginTime="0:0:0" Duration="0:0:2" RepeatBehavior="Forever" />
        </Storyboard>
    </Image.Resources>
    <Image.RenderTransform>
        <RotateTransform Angle="0" />
    </Image.RenderTransform>
</Image>
using System.Windows;
using System.Windows.Media.Animation;

namespace WpfSharp.UserControls
{
    /// <summary>
    /// Interaction logic for SpinningImage.xaml
    /// </summary>
    public partial class SpinningImage
    {
        public SpinningImage()
        {
            InitializeComponent();
        }

        public Storyboard Spinner
        {
            get { return _Spinner ?? (_Spinner = (Storyboard)FindResource("Spin360")); }
        } private Storyboard _Spinner;

        public bool SpinnerState
        {
            get { return (bool)GetValue(SpinnerStateProperty); }
            set { SetValue(SpinnerStateProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SpinnerState.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SpinnerStateProperty =
            DependencyProperty.Register("SpinnerState", typeof(bool), typeof(SpinningImage), new UIPropertyMetadata(false, OnSpinnerStatePropertyChanged));

        public static void OnSpinnerStatePropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            var view = source as SpinningImage;
            if (view == null) return;
            if ((bool)e.NewValue)
                view.Spinner.Begin();
            else
                view.Spinner.Stop();
        }
    }
}

Now to use this in XAML, it is quite simple.

            <wpfsharp:SpinningImage Name="ImageGraySpinner" Source="/Images/GraySpinner.png" Height="128" Width="128" SpinnerState="{Binding Path=IsExecuting}"/>

Feel free to enhance it. It probably would be nice to enhance this and make dependency properties for Storyboard variables such as Duration. It might even be a good idea to move the StoryBoard to code and eliminate the XAML in the custom control. Either way, this control is easy to stick into a library and use.

3 Comments

  1. mehmet naz says:

    Can you upload somewhere a solution using this usercontrol with workin example please ?

  2. […] UPDATE: Check out this more recent post: A SpinningImage control in WPF […]

Leave a Reply