Due to the imperfect scaling ability of GIF images, these are deprecated in WPF.
A work around though can be found here:
https://code.msdn.microsoft.com/windowsdesktop/CSWPFAnimatedGIF-3029aeb9/sourcecode?fileId=26331&pathId=41660693
This is how the control looks like:
/****************************** Module Header ******************************\
Module Name: AnimatedGIFControl.cs
Project: CSWPFAnimatedGIF
Copyright (c) Microsoft Corporation.
The CSWPFAnimatedGIF demonstrates how to implement
an animated GIF image in WPF.
This source is subject to the Microsoft Public License.
See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
All other rights reserved.
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
namespace Ellab.WPF.Utilities
{
public class AnimatedGIFControl : System.Windows.Controls.Image
{
private Bitmap _bitmap; // Local bitmap member to cache image resource
private BitmapSource _bitmapSource;
public delegate void FrameUpdatedEventHandler();
/// <summary>
/// Delete local bitmap resource
/// Reference: http://msdn.microsoft.com/en-us/library/dd183539(VS.85).aspx
/// </summary>
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool DeleteObject(IntPtr hObject);
/// <summary>
/// Override the OnInitialized method
/// </summary>
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
this.Loaded += new RoutedEventHandler(AnimatedGIFControl_Loaded);
this.Unloaded += new RoutedEventHandler(AnimatedGIFControl_Unloaded);
}
/// <summary>
/// Load the embedded image for the Image.Source
/// </summary>
void AnimatedGIFControl_Loaded(object sender, RoutedEventArgs e)
{
try
{
// Get GIF image from Resources
if (Ellab.WPF.Properties.Resources.ProgressIndicator != null)
{
_bitmap = Ellab.WPF.Properties.Resources.ProgressIndicator;
Width = _bitmap.Width;
Height = _bitmap.Height;
_bitmapSource = GetBitmapSource();
Source = _bitmapSource;
StartAnimate();
}
}
catch (Exception ex) { Ellab.Debug.GlobalDebug.debugForm.WriteText(ex); }
}
/// <summary>
/// Close the FileStream to unlock the GIF file
/// </summary>
private void AnimatedGIFControl_Unloaded(object sender, RoutedEventArgs e)
{
StopAnimate();
}
/// <summary>
/// Start animation
/// </summary>
public void StartAnimate()
{
ImageAnimator.Animate(_bitmap, OnFrameChanged);
}
/// <summary>
/// Stop animation
/// </summary>
public void StopAnimate()
{
ImageAnimator.StopAnimate(_bitmap, OnFrameChanged);
}
/// <summary>
/// Event handler for the frame changed
/// </summary>
private void OnFrameChanged(object sender, EventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal,
new FrameUpdatedEventHandler(FrameUpdatedCallback));
}
private void FrameUpdatedCallback()
{
ImageAnimator.UpdateFrames();
if (_bitmapSource != null)
_bitmapSource.Freeze();
// Convert the bitmap to BitmapSource that can be display in WPF Visual Tree
_bitmapSource = GetBitmapSource();
Source = _bitmapSource;
InvalidateVisual();
}
private BitmapSource GetBitmapSource()
{
IntPtr handle = IntPtr.Zero;
try
{
handle = _bitmap.GetHbitmap();
_bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally
{
if (handle != IntPtr.Zero)
DeleteObject(handle);
}
return _bitmapSource;
}
}
}
And the control can be used like this. First set the namespace:
xmlns:local="clr-namespace:Ellab.WPF.Utilities;assembly=Ellab.WPF"
Then use it like
<local:AnimatedGIFControl x:Name="GIFCtrl"/>
As always, feel free to comment, or ask.