Image UriSource and data binding

I am trying to associate a list of custom objects with a WPF image as follows:

<Image> <Image.Source> <BitmapImage UriSource="{Binding Path=ImagePath}" /> </Image.Source> </Image> 

But that will not work. This is the error I get:

"The 'UriSource' property or the 'StreamSource' property must be set."

What am I missing?

+56
data-binding wpf xaml
Aug 21 '08 at 17:21
source share
6 answers

WPF has built-in converters for certain types. If you bind the Image Source property to a string or Uri value, under the hood, WPF will use ImageSourceConverter to convert the value to ImageSource .

So,

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

will work if the ImageSource property is a string representation of a valid URI for the image.

You can, of course, collapse your own binding converter:

 public class ImageConverter : IValueConverter { public object Convert( object value, Type targetType, object parameter, CultureInfo culture) { return new BitmapImage(new Uri(value.ToString())); } public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } } 

and use it as follows:

 <Image Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}"/> 
+73
Aug 21 '08 at 18:38
source share
— -

This Atul Gupta article has sample code that covers several scenarios:

  • Associating a regular resource for the Source property in XAML
  • An image of the binding resource, but from the code
  • Linking a resource image in code using Application.GetResourceStream
  • Loading an image from a file path through a memory stream (the same applies when loading blog image data from a database)
  • Loading an image from the file path, but using the file path binding
  • Associating image data with a user control that internally has image control through a dependency property
  • The same as in paragraph 5, but also ensures that the file will not be locked on the hard drive
+23
May 14 '09 at 10:18
source share

You can also just set the Source attribute instead of using child elements. To do this, your class needs to return the image as a bitmap. Here is an example of how I did it.

 <Image Width="90" Height="90" Source="{Binding Path=ImageSource}" Margin="0,0,0,5" /> 

And the class property is just this

 public object ImageSource { get { BitmapImage image = new BitmapImage(); try { image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; image.CreateOptions = BitmapCreateOptions.IgnoreImageCache; image.UriSource = new Uri( FullPath, UriKind.Absolute ); image.EndInit(); } catch{ return DependencyProperty.UnsetValue; } return image; } } 

I suppose this might be a little more than a value converter, but this is another option.

+19
Aug 21 '08 at 17:45
source share

You must have an implementation of the IValueConverter interface that converts uri to image. Your convertible implementation of IValueConverter will look something like this:

 BitmapImage image = new BitmapImage(); image.BeginInit(); image.UriSource = new Uri(value as string); image.EndInit(); return image; 

Then you will need to use the converter in your binding:

 <Image> <Image.Source> <BitmapImage UriSource="{Binding Path=ImagePath, Converter=...}" /> </Image.Source> </Image> 
+9
Aug 21 '08 at 17:35
source share

The problem with the answer that was selected here is that when navigating back and forth, the converter will start every time the page is displayed.

This causes new file descriptors to be created continuously and blocks any attempt to delete the file since it is still in use. This can be verified using Process Explorer.

If the image file can be deleted at some point, such a converter can be used: using XAML to bind to System.Drawing.Image in the System.Windows.Image control

The disadvantage of this memory stream method is that the image (s) are loaded and decoded each time, and caching cannot be performed: "To prevent images from being decoded more than once, set the Image.Source property from Uri rather than using memory streams" Source: "Performance recommendations for Windows Store apps using XAML"

To solve the performance problem, the repository template can be used to provide a level of caching. Caching can occur in memory, which can cause memory problems, or in the form of thumbnail files that are located in a temporary folder that can be deleted when the application exits.

+6
Dec 15 '12 at 19:36
source share

you can use

Class ImageSourceConverter

to get what you want

  img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png"); 
+4
Oct 20 '13 at 18:00
source share



All Articles