如何在 WPF 中从图像源中释放图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16908383/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:55:07  来源:igfitidea点击:

How to release Image from Image Source in WPF

c#wpfimage

提问by Usher

Am loading image like below

正在加载如下图像

XAML

XAML

<Image Stretch="None" Grid.Row="16" Height="70" HorizontalAlignment="Left" Name="imgThumbnail" VerticalAlignment="Top" Width="70" Grid.RowSpan="3" Margin="133,1,0,0" Grid.Column="2" Grid.ColumnSpan="2" />

CodeBehind

代码隐藏

if (Path.GetFileNameWithoutExtension(filePath).ToLower().Contains(slugName.ToLower() + "_70x70"))
{
    imgThumbnail.BeginInit();
    imgThumbnail.Stretch = Stretch.UniformToFill;
    imgThumbnail.Source = new BitmapImage(new Uri(filePath));
    imgThumbnail.EndInit();
    count = count + 1;
}

Above code work fine , now I have a delete button next to my thumbnail, if delete button called I suppose to delete all the images from the source location.

上面的代码工作正常,现在我的缩略图旁边有一个删除按钮,如果调用了删除按钮,我想从源位置删除所有图像。

Here is the code to delete the image files

这是删除图像文件的代码

internal int Remove(string slugName, DirectoryInfo outputFolder)
{
    Helper.MetadataView.imgThumbnail.Source = null;

    foreach (string filePath_ToBeDeleted in filePathList_ToBeDeleted)
    {
        if (File.Exists(filePath_ToBeDeleted))
        {
            Helper.MetadataView.imgThumbnail.IsEnabled = false;
            File.Delete(filePath_ToBeDeleted);
            count += 1;
            }
        }
        return count;
    }
    return 0; // slugName == null
}

I tried to source to be null and delete, but it throws exception like below

我试图将 source 设为 null 并删除,但它抛出如下异常

The process cannot access the file '\serv1\Dev\Images\730_Test4_0406_70x70.jpg' because it is being used by another process.

该进程无法访问文件“\serv1\Dev\Images\730_Test4_0406_70x70.jpg”,因为它正被另一个进程使用。

Am not sure how to dispose, please someone guide me.

不知道怎么处理,求大神指点。

回答by Nikhil Agrawal

You should not use that Imagedirectly in your application if you want to delete or move it.

Image如果要删除或移动它,则不应直接在应用程序中使用它。

imgThumbnail.Source = new BitmapImage(new Uri(filePath));

Instead, do this:

相反,请执行以下操作:

BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(filePath);
image.EndInit();
imgThumbnail.Source = image;

For more read this

欲了解更多,请阅读本文

回答by Apfelkuacha

To have a good code-reuse a binding converter could be used:

为了实现良好的代码重用,可以使用绑定转换器:

namespace Controls
{
    [ValueConversion(typeof(String), typeof(ImageSource))]
    public class StringToImageSourceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is string valueString))
            {
                return null;
            }
            try
            {
                ImageSource image = BitmapFrame.Create(new Uri(valueString), BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.OnLoad);
                return image;
            }
            catch { return null; }
        }

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

And there is a string for binding, for example

并且有一个用于绑定的字符串,例如

public string MyImageString { get; set; } = @"C:\test.jpg"

And in the UI the converter is used, in my case from the Library named "Controls"

在 UI 中使用了转换器,在我的例子中来自名为“Controls”的库

<Window x:Class="MainFrame"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:Controls;assembly=Controls">
    <Window.Resources>
        <controls:StringToImageSourceConverter x:Key="StringToImageSourceConverter" />
    </Window.Resources>
    <Grid>
        <Image Source="{Binding MyImageString, Converter={StaticResource StringToImageSourceConverter}}" />
    </Grid>
</Window>