I have a WPF application that needs to provide feedback to the user about an internal state. The design is to have three images, call them Red, Yellow, and Green. One of these images will be displayed at a time depending on the state. Here are the points:
- The three images are in Properties.Resources in the code-behind
- Only one of the images will be shown at a time.
- The state change comes from a process in code-behind and not from the user.
- I would like to bind an image control so that I can change the image from code-behind.
I’m assuming I’ll need an image converter to change the JPG image to an image source such as:
[ValueConversion(typeof(System.Drawing.Bitmap), typeof(ImageSource))]
public class BitmapToImageSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var bmp = value as System.Drawing.Bitmap;
if (bmp == null)
return null;
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bmp.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
I’d prefer to convert the images once during initialization and keep a list of Image sources. I’m also assuming I’ll need a dependency property to bind the control to, but I’m not sure how to set that up with this list of image sources:
// Dependancy Property for the North Image
public static readonly DependencyProperty NorthImagePathProperty
= DependencyProperty.Register(
"NorthImagePath",
typeof(ImageSource),
typeof(MainWindow),
new PropertyMetadata("**Don't know what goes here!!!**"));
// Property wrapper for the dependancy property
public ImageSource NorthImagePath
{
get { return (ImageSource)GetValue(NorthImagePathProperty); }
set { SetValue(NorthImagePathProperty, value); }
}
Although an image resource in a WPF project generates a
System.Drawing.Bitmap
property inResources.Designer.cs
, you could directly create aBitmapImage
from that resource. You only need to set the Build Action of the image file toResource
(instead of the defaultNone
).If you have a file
Red.jpg
in theResources
folder of your Visual Studio Project, creating aBitmapImage
would look like shown below. It uses a WPF Pack Uri.If you have an
Image
control declared somewhere in XAML like this:you could simply set the
Source
property of the image to your BitmapImage in code behind:In case you prefer to set the
Source
property by binding you could create astring
property that returns the image URI. The string will automatically be converted to aBitmapImage
by a built-inTypeConverter
in WPF.In XAML you would bind to that property like this:
Of course you could as well declare the property to be of type
ImageSource
and bind in the same way:
Now you could pre-load your images and put them into the property as needed:
UPDATE: After all, your images do not need to be resources in the Visual Studio project. You could just add a project folder, put the image files into that folder and set their Build Action to
Resource
. If for example you call the folderImages
, the URI would bepack://application:,,,/Images/Red.jpg
.