How to force Image control to close the file that it opens in wpf
Asked Answered
D

1

5

I have an image on my wpf page which opens an image file form hard disk. The XAML for defining the image is:

  <Image  Canvas.Left="65" Canvas.Top="5" Width="510" Height="255" Source="{Binding Path=ImageFileName}"  />

I am using Caliburn Micro and ImageFileName is updated with the name of file that image control should show.

When the image is opend by image control, I need to change the file. But the file is locked by image control and I can not delete or copy any mage over it. How can I force Image to close the file after it opened it or when I need to copy another file over it?

I checked and there is no CashOptio for image so I can not use it.

Danell answered 12/10, 2012 at 20:41 Comment(4)
Post you Get for ImageFileName. Are you closing the file there?Hynda
@Blam: The ImageFileName is something such as this: c:\tmp\testimage.jpg and I am not opening or closing it by myself. It is the Image control which opens it and not closing it.Danell
See this question and answer. In your case it may make sense to write a binding converter that converts the file name to an ImageSource.Gerianne
Exactly. Need a different pattern so the control is not accessing a file. Do it in the converter or the get.Hynda
G
13

You could use a binding converter like below that loads an image directly to memory cache by setting BitmapCacheOption.OnLoad. The file is loaded immediately and not locked afterwards.

<Image Source="{Binding ...,
                Converter={StaticResource local:StringToImageConverter}}"/>

The converter:

public class StringToImageConverter : IValueConverter
{
    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        object result = null;
        var path = value as string;

        if (!string.IsNullOrEmpty(path))
        {
            var image = new BitmapImage();
            image.BeginInit();
            image.CacheOption = BitmapCacheOption.OnLoad;
            image.UriSource = new Uri(path);
            image.EndInit();
            result = image;
        }

        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Even better, load the BitmapImage directly from a FileStream:

public object Convert(
    object value, Type targetType, object parameter, CultureInfo culture)
{
    object result = null;
    var path = value as string;

    if (!string.IsNullOrEmpty(path) && File.Exists(path))
    {
        using (var stream = File.OpenRead(path))
        {
            var image = new BitmapImage();
            image.BeginInit();
            image.CacheOption = BitmapCacheOption.OnLoad;
            image.StreamSource = stream;
            image.EndInit();
            result = image;
        }
    }

    return result;
}
Gerianne answered 12/10, 2012 at 21:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.