[英]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并将其CacheOption
为OnLoad
。 然后,框架将立即加载文件而不是保持打开状态。
<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指向本地磁盘上的文件 - 您就无法删除它。 我想到了以下两种方法:
由于您具有实际图像的路径 - 为什么不将其复制到TEMP文件夹并绑定到此路径。 这样你就不会指现在可以删除的实际图像了。
使用/构建一个http主机(CMS)用于图像文件(如)imgur(StackOverflow也使用它)。 始终保存/托管文件。 那样ImagesSource就是一个http uri。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.