WPF Image element locks my local file
When using the Image element and specifying a local resource Uri in the Source attribute that resource will be locked by your application's process.
<Image Source="C:\Image\Josh.png" />
The file can't be deleted or modified whilst it's locked and this can be a problem if the image was generated and the application wants to clean it up when the user has finished looking at it. There is a simple work around for this, specifying the BitmapImage directly and specifying the CacheOption as
OnLoad:
<Image>
<Image.Source>
<BitmapImage UriSource="C:\Image\Josh.png" CacheOption="OnLoad" />
</Image.Source>
</Image>
But
However, there is one big problem with this. The UriSource doesn't work with a binding, e.g.:
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding MyImageUrl}" CacheOption="OnLoad" />
</Image.Source>
</Image>
The good news is, there's another workaround for this by implementing an IValueConverter that returns a BitmapImage with the CacheOption set to OnLoad.
public class UriToCachedImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null;
if (!string.IsNullOrEmpty(value.ToString()))
{
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(value.ToString());
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.EndInit();
return bi;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException("Two way conversion is not supported.");
}
}
Now we can go back to using the Image tag alone, and use our new converter to return a cached BitmapImage:
<Image Source="{Binding MyImageUrl, Converter={StaticResource uriToImageConv}}"/>
... where uriToImageConv is the key of a static resource of type UriToCachedImageConverter.
Thanks to WiredPrairie for the
inspiration for this workaround.

Post By
Josh Twist
12:58
07 Aug 2007
» Next Post:
Part III. Grabbing the ScreenShot
« Previous Post:
Part II. Storing the Feedback Data
Comments:
Posted by
GioGio
@
19 Nov 2008
02:41
hey there,
that's exactly, what I needed. Thx for that.
Now, I have a question:
I added the Class UriToCachedImageConverter to my project, but how can I add a "static resource" of this class?
Posted by
Josh
@
19 Nov 2008
12:05
Check out this post, Xaml. Using Resources:
http://www.thejoyofcode.com/Xaml._Using_Resources.aspx
Posted by
Ryan O'Neill
@
04 Feb 2009
02:41
Brilliant, I kind of thought it was doing something like that but I just could not track it down. Now I can delete my images after I remove them from a ListView.
Thanks for post, it was very helpful.
Ryan
Posted by
Patrik Fatoric
@
10 Feb 2009
16:06
Hi,
I have a similar problem, but my image is part of control template in a Button which is situated in a DataTemplate of WPF DataGrid.
The DataTemplate is loaded dynamically as resource dictionary.
My problem is that I cannot use local resurces statically linked to my DataTemplate so I cannot
use the DataConverter.
What could I do ?
I find out, when I intentional chage the ImageSource to another existing image on disk the system release the first one. After that the first image is free to delete or chage.
Is there a better solution ?
My code ...
<Button x:Name="Img1" Width="35" Height="35">
<Button.Template>
<ControlTemplate>
<Image x:Name="img" Source="{Binding Path=Slika}" width="32" Height="32"/></ControlTemplate> </Button.Template>