我正在尝试将自定义对象列表绑定到WPF图像,如下所示:
1 2 3 4 5
| <Image>
<Image.Source>
<BitmapImage UriSource="{Binding Path=ImagePath}" />
</Image.Source>
</Image> |
但是它不起作用。这是我得到的错误:
"必须设置属性\\'UriSource \\'或属性\\'StreamSource \\'。"
我想念什么?
WPF具有某些类型的内置转换器。如果将Image的Source属性绑定到string或Uri值,则WPF在幕后将使用ImageSourceConverter将值转换为ImageSource。
所以
1
| <Image Source="{Binding ImageSource}"/> |
如果ImageSource属性是图像的有效URI的字符串表示形式,则可以使用。
您当然可以滚动自己的Binding转换器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class ImageConverter : IValueConverter
{
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
return new BitmapImage(new Uri(value.ToString()));
}
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
} |
并像这样使用它:
1
| <Image Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}"/> |
Atul Gupta的这篇文章的示例代码涵盖了几种场景:
常规资源图像绑定到XAML中的Source属性
绑定资源映像,但来自代码后面
通过使用Application.GetResourceStream在代码后绑定资源映像
通过内存流从文件路径加载图像(从数据库加载博客图像数据时同样适用)
从文件路径加载图像,但是通过使用绑定到文件路径
通过依赖属性将图像数据绑定到内部具有图像控件的用户控件
与第5点相同,但还要确保文件不会被锁定在硬盘上
您也可以简单地设置Source属性,而不使用子元素。为此,您的类需要将图像作为位图图像返回。这是我完成该操作的一种方式的示例
1 2 3
| <Image Width="90" Height="90"
Source="{Binding Path=ImageSource}"
Margin="0,0,0,5" /> |
class属性就是这个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public object ImageSource {
get {
BitmapImage image = new BitmapImage();
try {
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
image.UriSource = new Uri( FullPath, UriKind.Absolute );
image.EndInit();
}
catch{
return DependencyProperty.UnsetValue;
}
return image;
}
} |
我想它可能比值转换器要多一些工作,但这是另一种选择。
您需要实现IValueConverter接口,该接口将uri转换为图像。您的IValueConverter的Convert实现将如下所示:
1 2 3 4 5 6
| BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(value as string);
image.EndInit();
return image; |
然后,您将需要在绑定中使用转换器:
1 2 3 4 5
| <Image>
<Image.Source>
<BitmapImage UriSource="{Binding Path=ImagePath, Converter=...}" />
</Image.Source>
</Image> |
此处选择答案的问题是,在来回导航时,每次显示页面时都会触发转换器。
这将导致连续创建新的文件句柄,并且将阻止任何删除该文件的尝试,因为该文件仍在使用中。可以使用Process Explorer来验证。
如果图像文件可能在某个时候被删除,则可以使用如下所示的转换器:
使用XAML将System.Drawing.Image绑定到System.Windows.Image控件中
此内存流方法的缺点在于,每次都会对图像进行加载和解码,并且无法进行缓存:
"为了防止图像被多次解码,请从Uri分配Image.Source属性,而不要使用内存流"
来源:"使用XAML的Windows Store应用程序的性能提示"
为解决性能问题,存储库模式可用于提供缓存层。缓存可能发生在内存中,这可能会导致内存问题,也可能是缩略图文件驻留在temp文件夹中,可以在应用程序退出时清除。
您可以使用
ImageSourceConverter class
得到想要的东西
1
| img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.webp"); |