Wednesday, January 16, 2013

Animating an Image in WPF using Timer

How to animate and Image in WPF using Timer?

For further discussion please visit Animating an Image in WPF blog. Here I just simply pasted the alternative solution on how to animate an image in WPF using the Timer class (instead of Animation class).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using System.Timers;

namespace CodesDirectory.Controls
{
    public partial class AnimatableImage : Image
    {
        #region Privates

        private const int TIME_MILLISECONDS_PER_IMAGEFRAME = 75;
        private Timer __timer = null;
        private int __currentFrameIndex = 0;

        #endregion

        public AnimatableImage()
        {
            InitializeComponent();
            this.__timer = new Timer();
            this.__timer.Elapsed += new ElapsedEventHandler(__timer_Elapsed);
        }

        void __timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (!this.Dispatcher.CheckAccess())
            {
                this.Dispatcher.Invoke(new Action<object, ElapsedEventArgs>(this.__timer_Elapsed), new object[] { sender, e });
                return;
            }
            if (!object.ReferenceEquals(this.Source, null))
            {
                this.Source = ((BitmapFrame)this.Source).Decoder.Frames[this.__currentFrameIndex];
                __currentFrameIndex++;
                if (this.__currentFrameIndex >= this.FrameCount) this.__currentFrameIndex = 0;
            }
        }

        #region Methods

        private void InitializeImageFrames()
        {
            if (object.ReferenceEquals(this.Source, null)) return;
            BitmapFrame bf = this.Source as BitmapFrame;
            if (object.ReferenceEquals(bf, null)) bf = BitmapFrame.Create((BitmapSource)this.Source);
            if (!object.ReferenceEquals(bf.Decoder, null))
            {
                this.FrameCount = bf.Decoder.Frames.Count;
                this.IsFramesInitiated = true;
            }
        }

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if (object.Equals(e.Property, Image.SourceProperty))
            {
                this.InitializeImageFrames();
                this.__timer.Interval = AnimatableImage.TIME_MILLISECONDS_PER_IMAGEFRAME;
                base.OnPropertyChanged(e);
            }
        }

        public void StartAnimate()
        {
            if (!this.IsAnimating && this.IsFramesInitiated)
            {
                this.__timer.Start();
                this.IsAnimating = true;
            }
        }

        public void StopAnimation()
        {
            if (this.IsAnimating)
            {
                this.__timer.Stop();
                this.IsAnimating = false;
            }
        }

        #endregion

        #region Properties

        public bool IsAnimating { get; private set; }

        public int FrameCount { get; private set; }

        private bool IsFramesInitiated { get; set; }

        #endregion
    }
}

No comments:

Post a Comment

Place your comments and ideas