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)
11 responses to “Databinding a System.Drawing.Image into a WPF System.Windows.Image”
Thanks a lot!
Short and clear explanation!
I’m also learning WPF as a background thing
I tried this, and my images, which have a transparent background, are now displayed with a black background.
@Alex; try poking around in the System.Windows.Media.Imaging namespace. My guess is that the System.Windows.Media.Imaging.BitmapImage class isn’t handling the alpha channel present in your image. I notice that there are PngBitmapDecoder and PngBitmapEncoder classes, which may or may not help.
(http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.aspx)
To preserve all features of the original image, I think you should replace
image.Save(memoryStream, ImageFormat.Bmp);
with
image.Save(memoryStream, image.RawFormat);
By doing this, you’ll keep features like transparency/alpha channels from image formats like PNG.
Thanks, Gunnar — Updated.
Great, thanks!
[…] http://www.stevecooper.org/index.php/2010/08/06/databinding-a-system-drawing-image-into-a-wpf-system… […]
Hey Steve. Thanks for the post. I wanted to share a VB.Net conversion I made on the code you provided in case anybody else is looking for one.
http://blakepell.wordpress.com/2011/12/22/databinding-a-system-drawing-image-in-wpf-with-vb-net/
Thanks a lot! I’ve spent 2 days on it without any result.
where is the corret position of this code?
I don’t know to create a good static resources.
[…] The original article that I found to help me was posted by Steve Cooper and can be found at http://www.stevecooper.org/index.php/2010/08/06/databinding-a-system-drawing-image-into-a-wpf-system… […]