I’m learning WPF, very slowly, as a background thing.
I’m working very slowly through some WPF at the moment, and discovered something I thought was really odd. The classic .Net Image class — System.Drawing.Image — can’t be easily databound into the WPF Image control.
That seemed crazy to me — it’s like having a `PictureBox` control without an `Image` property. I resolved to fix it in the most ‘WPFy’ way I could.
What I’d tried was binding a ListView to a list of objects, like so;
Id bound to an object which declares two properties;
string DisplayName { get; }
System.Drawing.Image Image { get; set; }
I wanted to populate a `DataTemplate` but if I did this in my template;
The text appears but the image does not. It turns out that WPF can’t find a suitable converter.
So, thanks to [Reed Copsey](http://reedcopsey.com/) and his very helpful [pointer on Stack Overflow](http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/833ca60f-6a11-4836-bb2b-ef779dfe3ff0/), and [this tutorial](http://www.switchonthecode.com/tutorials/wpf-tutorial-binding-converters), I’ve found a way I’m happy with; one that doesn’t involve c# code-behind.
I’ve created an `IValueConverter` which does the conversion from `System.Drawing.Image` to `System.Windows.Media.ImageSource`. A big thank-you to [Matt Galbraith of Microsoft](http://social.msdn.microsoft.com/profile/matt%20galbraith%20-%20msft) for providing the core code;
using System;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Windows.Data;
namespace System.Windows.Media
{
///
///
[ValueConversion(typeof(System.Drawing.Image), typeof(System.Windows.Media.ImageSource))]
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
// empty images are empty…
if (value == null) { return null; }
var image = (System.Drawing.Image)value;
// Winforms Image we want to get the WPF Image from…
var bitmap = new System.Windows.Media.Imaging.BitmapImage();
bitmap.BeginInit();
MemoryStream memoryStream = new MemoryStream();
// Save to a memory stream…
image.Save(memoryStream, image.RawFormat);
// Rewind the stream…
memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
bitmap.StreamSource = memoryStream;
bitmap.EndInit();
return bitmap;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
}
Then you need to bring the image converter into XAML as a resource. Add the namespace declaration to the window;
xmlns:med=”clr-namespace:System.Windows.Media”
Stick an instance of the `ImageConverter` into a static resource;
Then you can use it in XAML to bind directly to the Image, using the new converter;
So. A re-usable converter which allows databinding directly to GDI image objects.
Originally discussed [on stack overflow](http://stackoverflow.com/questions/3427034/using-xaml-to-bind-to-a-system-drawing-image-into-a-system-windows-image-control)