Binding Image.Source to String in WPF?

Let’s break down what you’re doing.

<Image Source="{Binding ImageSource}" />

For this to work, the binding source needs to be either an ImageSource, or a string representing a URI to an image file. So let’s take a look at what the ImageSource property actually is.

public string ImageSource { get; set; }

One problem here is that ImageSource isn’t raising PropertyChanged events. So WPF won’t update the binding target when you update the property.

But also, ImageSource isn’t an ImageSource, it’s a string. That’s okay, but WPF is going to interpret that string as a URI. What is that URI?

ImageSource = Base64StringToImage(BIG_HONKING_STRING).Source.ToString(); 

This is the nub of your problem. The ImageSource string isn’t actually a URI, because your image isn’t an addressable resource. Base64StringToImage creates an in-memory ImageSource from the base64 string, then return an Image with that as its Source. Then you take the Image’s Source (which is an ImageSource object), and stringise that. That might work if the ImageSource had come from a file or URL, but it didn’t: it came from a HBITMAP. So the result of ToString() is going to be meaningless. So ImageSource is being set to something meaningless, and your Image is trying to interpret this meaningless thing as the URL of a bitmap file.

So to fix this you need to do three things:

  1. Raise the PropertyChanged event for the ImageSource property (or make it a dependency property).
  2. Change the ImageSource property to be of type ImageSource instead of type string (so that it can contain URL-less image sources).
  3. Change your setter call to set ImageSource to Base64StringToImage(...).Source — i.e. remove the ToString() call. Better still, change Base64StringToImage to return an ImageSource rather than an Image: creating an Image element just creates overhead because all you’re really interested in is the BitmapSource.

Leave a Comment