Animated Gif in WPF using Windows Forms Control

Loading an animated gif into WPF has been a challenge since the version 1 release. WPF does not support loading an animated gifs directly into an declarative <Image> or by code, and hence developers have come out with various workarounds. Some use a raw technique – writing few lines of code which extracts the frames of the GIF and animate them.  One other way to do is using the <MediaElement> FrameworkElement which is in the namespace System.Windows.Controls. <MediaElement> wraps the MediaPlayer class for declarative use and hence it supports both audio and video files. Using MediaElement you can load the animated gif the following way:

<MediaElement Source="file://D:\anim.gif"/>

Remember it is important to use “file://” and an absolute path for loading the gif. So you cannot embed the image to a resource file and now you know one of the limitations of it. Every approach does have advantages and limitations of its own, its important to use the right approach based on the project needs.

Another possible way is by making the working Jack do the trick – Yeah I meant lets go back to Win Forms picture box to do the magic. We know PictureBox seamlessly loaded the animated gifs in Win Form days. Wait a minute did I say lets change the project from WPF to Win Forms? No I didn’t. What I said is lets integrate the PictureBox alone to the WPF project. To use the right word, I should say that we need to host the Windows Forms Control in WPF. To host a Windows Forms Control you need to make use of the class WindowsFormsHost which appears in the System.Windows.Forms.Integration namespace in assembly WindowsFormsIntegration.dll.

Lets get to the code. The first step to do is add a reference to System.Windows.Forms.dll and WindowsFormsIntegration.dll to your WPF based project.

References

Add the following namespaces to your XAML Code.

<Window x:Class="WpfApplication2.Window1"
    xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
    xmlns:winForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

Now you can host the PictureBox inside the WindowsFormsHost and set its Name.

    <Grid>
        <wfi:WindowsFormsHost>
            <winForms:PictureBox x:Name="pictureBoxLoading">
            </winForms:PictureBox>
        </wfi:WindowsFormsHost>
    </Grid>

In your code behind(Window1.xaml.cs), add this code to the Window_Loaded Event:

private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.pictureBoxLoading.Image = System.Drawing.Image.FromFile("anim.gif"); ;
        }

Key points before execution:

  1. Make sure you provide the right path to load the image
  2. You can also load it from a resource file.

Since Windows Forms has several interesting built in controls that WPF lacks, using this technique you can make your favorite Windows Forms control work in WPF.

Cheers!

Understanding Dependency Property

Everyone who get introduced to Windows Presentation Foundation(WPF) are familiar with this term. But lot many get confused on it or never get what it is. I will try and make this post very simple so that it is easier to understand. My intentions are not to provide the complete technical stuff behind the Dependency property, but to keep things simple to understand and to get started. You should probably work on this lot many times to understand it better.

If you are not new to .net or any other OOP language, you are not new to Property. Dependency property was introduced in .net 3.0 and it is all together new implementation of normal properties. Dependency property differ in terms of its storage mechanism, it uses Sparse Storage and its implementation saves per-instance memory compared to a typical .NET property. However benefits of dependency property is more than just storage. One of the significances of Dependency property is its support for notification change – that means any change in the value of the property is notified down the element tree in WPF. This point particularly becomes very important to understand this.

Before I completely get on with Dependency property, let me give a gist of what attached property is. Let me explain this in a way a lay man understands: Consider a “<Canvas></Canvas>” element in your XAML. Now if you want to add a child element “<TextBlock>” to it, how do you place them in the canvas? – Here it is:

<Canvas>
       <TextBlock Canvas.Top=”100″ Canvas.Left=”100″ Text=”Hello World”/>
</Canvas>

OR an example with a Grid

<Grid>
   <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
   </Grid.ColumnDefinitions>
   <Grid.RowDefinitions>
      
<RowDefinition/>
      
<RowDefinition/>
   </Grid.RowDefinitions>
  
<TextBlock Grid.Column=”0″ Grid.Row=”0″ Text=”Hello World  1″/>
  
<TextBlock Grid.Column=”1″ Grid.Row=”0″ Text=”Hello World 2″/>
  
<TextBlock Grid.Column=”0″ Grid.Row=”1″ Text=”Hello World 3″/>
  
<TextBlock Grid.Column=”1″ Grid.Row=”1″ Text=”Hello World 4″/> 
 
</Grid>

So what we do is we set the Canvas’s Top and Left property in the TextBlock child element or even the Grid’s Column and Row property in the child elements. This is achieved using attached property.

So here is the MSDN explanation: “An attached property is intended to be used as a type of global property that is settable on any object. One purpose of an attached property is to allow different child elements to specify unique values for a property that is actually defined in a parent element.”

In the above example, we see the property element of a parent is changed by the child, and the same gets reflected throughout the child elements. I have explained this so that you don’t confuse attached property with dependency property.

Let us extend couple of lines of code more and now understand dependency property.

And here it is:

<Canvas>
<Slider Canvas.Top=”10″ Canvas.Left=”10″ Name=”MySlider” Minimum=”10″ Maximum=”1000″ Ticks=”100″ Width=”300″/>
 <Ellipse Canvas.Top=”130″ Canvas.Left=”150″ Width=”{Binding ElementName=MySlider, Path=Value}” Height=”{Binding ElementName=MySlider, Path=Value}” Fill=”Red”/>
 </Canvas>

The output of the above example is: When the slider is moved, automatically the ellipse gets larger or smaller based on the value of the slider. So what we understand from this is without writing event handlers or any code behind to handle the slider movement and the ellipse height and width setters – we achieve this. This is because the property “Value” of the slider is a dependency property and it notifies the change to all the elements in the XAML, and since the Ellipse’s width and height are bound to the “Slider.Value” it automatically reflects the change.

This was just an introduction, there are couple of more things I want to cover like – creating your own dependency properties for the custom controls etc, which will be updated in the next post.

Cheers!