繁体   English   中英

如何在使用XAML获取图像资源后释放/缓存它们

[英]How to release/caching image resources after get them using XAML

目前我正在使用prism 6进行WPF项目,尽可能避免代码隐藏。 我在ViewModel中有一个变量,它包含存储相关图像的本地路径。 在View中,我将Image控件的source属性绑定到ViewModel的变量,我可以显示图像。

当我仍需要在视图中显示图像时,我需要从磁盘中删除图像时出现问题。 然后,如果我这样做,我会得到典型的“图像正在使用中”。 我在论坛中读到了关于图像缓存的问题,我想知道是否可以在这种情况下应用它来避免这种行为,如果可能的话只使用XAML。

我正在使用这种方法:

<Border Grid.Column="0" BorderThickness="2" BorderBrush="#808080" Height="300" 
        Width="300" Background="#FCFCFC">
    <Image Height="350" Width="350" HorizontalAlignment="Center" 
           VerticalAlignment="Center" Source="{Binding ImageUri}"/>
</Border>

您无需在ViewModel创建ImageSource对象。 相反,只需创建一个byte[]类型的属性,您可以使用标准IO函数从文件中设置该属性。 然后,您可以将Image控件的Source属性绑定到此字节数组 - 控件将自动处理到可显示图像的转换。

请参阅我对此问题的回答,了解以异步方式处理此问题的方法。

读取文件后,您可以根据需要将其删除。 如果图像来自某些外部源,例如Web下载,您可以直接使用数据,甚至根本不需要将其保存到磁盘。

您可以为此编写转换器以将文件名转换为字节

public class FilenameToBytesConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }
        var path = (string)value;

        if (!File.Exists(path))
        {
            return null;
        }

        return File.ReadAllBytes(path);
    }

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

并在视图中使用它

<Window ...
        xmlns:Converters="clr-namespace:YourNamespacePath.Converters"/>

    <Window.Resources>
        <Converters:FilenameToBytesConverter x:Key="FilenameToBytesConverter"/>
    </Window.Resources>

    <Image Source="{Binding ImageUri, Converter={StaticResource FilenameToBytesConverter}}"/>

如果可以在调用InitializeComponent(MainWindow或UserControl)之前分配DataContext,则可以在XAML中显式创建BitmapImage并将其CacheOptionOnLoad 然后,框架将立即加载文件而不是保持打开状态。

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding ImageUri}" CacheOption="OnLoad"/>
    </Image.Source>
</Image>

如果必须在InitializeComponent之后设置DataContext或ImageUri属性,则可以添加ImageSource类型的属性

public ImageSource Image
{
    get { return BitmapFrame.Create(
              ImageUri, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); }
}

byte[]

public byte[] Image
{
    get { return File.ReadAllBytes(ImageUri.LocalPath); }
}

并绑定到它:

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

或异步提高UI的响应能力:

<Image Source="{Binding Image, IsAsync=True}"/>

只要您将ImageSource指向本地磁盘上的文件 - 您就无法删除它。 我想到了以下两种方法:

  1. 由于您具有实际图像的路径 - 为什么不将其复制到TEMP文件夹并绑定到此路径。 这样你就不会指现在可以删除的实际图像了。

  2. 使用/构建一个http主机(CMS)用于图像文件(如)imgur(StackOverflow也使用它)。 始终保存/托管文件。 那样ImagesSource就是一个http uri。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM