Some technical things, mostly odd happenings from a remote office RSS Feed


WPF, binding to an image without file access exceptions
You can run into file access errors when using images in WPF. By default, the .Net Framework locks the image until it's not used and the garbage collector decides to release the reference. For example, the following snippet displays an image but a file access error occurs if the application, or the user, tries to modify or delete the image file from the file system.
<Image Source="d:\vertigo.png" />
You can change how the framework manages the reference to the image with the BitmapImage.CacheOption property. The following snippet specifies that the image is loaded and the reference is released, so the image on the file system can be modified or deleted.
<Image>
  <Image.Source>
    <BitmapImage UriSource="d:\vertigo.png" CacheOption="OnLoad"></BitmapImage>
  </Image.Source>
</Image>
But the UriSource property does not support binding, so you cannot do something simple like the following:
<Image>
  <Image.Source>
    <!-- this does not work -->
    <BitmapImage UriSource="{Binding Path=ImagePath}" CacheOption="OnLoad"></BitmapImage>
  </Image.Source>
</Image>
Instead, you can do your own UriSource binding by creating a converter that takes in a path to the image and returns a BitmapImage object. For example, the following XAML binds the Source property to ImagePath (which is the path to the image), along with a converter that returns a BitmapImage object.
<local:ImagePathConverter x:Key="ImagePathConverter"/>
<Image Source="{Binding Path=ImagePath, Converter={StaticResource ImagePathConverter}}" />
The converter is pretty straightforward: creates a BitmapImage object, sets the CacheOption property, and returns the object. So now you can data bind to an image and still modify or delete the image from the file system without file access errors.
public class ImagePathConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, System.Globalization.CultureInfo culture)
    {
        // value contains the full path to the image
        string path = (string)value;

        // load the image, specify CacheOption so the file is not locked
        BitmapImage image = new BitmapImage();
        image.BeginInit();
        image.CacheOption = BitmapCacheOption.OnLoad;
        image.UriSource = new Uri(path);
        image.EndInit();

        return image;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException("The method or operation is not implemented.");
    }

 
Posted by Ralph Arvesen | 4 Comments | Trackback Url | Bookmark with:        
Tags:

Links to this Post

Comments

Monday, 8 Sep 2008 02:51 by Net Framework Development
Nice code example.... awesome post!!!

Monday, 22 Mar 2010 04:03 by Steve T
Saved me a lot of time - thanks!!

Name:
URL:
Email:
Comments:

CAPTCHA Image Validation