.net 图像 UriSource 和数据绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20586/
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
Image UriSource and Data Binding
提问by urini
I'm trying to bind a list of custom objects to a WPF Image like this:
我正在尝试将自定义对象列表绑定到 WPF 图像,如下所示:
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding Path=ImagePath}" />
</Image.Source>
</Image>
But it doesn't work. This is the error I'm getting:
但它不起作用。这是我得到的错误:
"Property 'UriSource' or property 'StreamSource' must be set."
“必须设置属性 'UriSource' 或属性 'StreamSource'。”
What am I missing?
我错过了什么?
回答by Brian Leahy
WPF has built-in converters for certain types. If you bind the Image's Sourceproperty to a stringor Urivalue, under the hood WPF will use an ImageSourceConverterto convert the value to an ImageSource.
WPF 具有某些类型的内置转换器。如果您将 Image 的Source属性绑定到 astring或Uri值,则在后台 WPF 将使用ImageSourceConverter将值转换为ImageSource.
So
所以
<Image Source="{Binding ImageSource}"/>
would work if the ImageSource property was a string representation of a valid URI to an image.
如果 ImageSource 属性是图像的有效 URI 的字符串表示形式,则将起作用。
You can of course roll your own Binding converter:
您当然可以推出自己的绑定转换器:
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();
}
}
and use it like this:
并像这样使用它:
<Image Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}"/>
回答by Drew Noakes
This articleby Atul Gupta has sample code that covers several scenarios:
Atul Gupta 的这篇文章包含涵盖多种场景的示例代码:
- Regular resource image binding to Source property in XAML
- Binding resource image, but from code behind
- Binding resource image in code behind by using Application.GetResourceStream
- Loading image from file path via memory stream (same is applicable when loading blog image data from database)
- Loading image from file path, but by using binding to a file path Property
- Binding image data to a user control which internally has image control via dependency property
- Same as point 5, but also ensuring that the file doesn't get's locked on hard-disk
- 常规资源图像绑定到 XAML 中的 Source 属性
- 绑定资源图像,但来自背后的代码
- 使用 Application.GetResourceStream 在后面的代码中绑定资源图像
- 通过内存流从文件路径加载图像(从数据库加载博客图像数据时同样适用)
- 从文件路径加载图像,但使用绑定到文件路径属性
- 通过依赖属性将图像数据绑定到内部具有图像控件的用户控件
- 与第 5 点相同,但也要确保文件不会被锁定在硬盘上
回答by palehorse
You can also simply set the Source attribute rather than using the child elements. To do this your class needs to return the image as a Bitmap Image. Here is an example of one way I've done it
您也可以简单地设置 Source 属性而不是使用子元素。为此,您的类需要将图像作为位图图像返回。这是我完成的一种方法的示例
<Image Width="90" Height="90"
Source="{Binding Path=ImageSource}"
Margin="0,0,0,5" />
And the class property is simply this
而 class 属性就是这个
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;
}
}
I suppose it may be a little more work than the value converter, but it is another option.
我想它可能比值转换器要多一些工作,但它是另一种选择。
回答by Dale Ragan
You need to have an implementation of IValueConverterinterface that converts the uri into an image. Your Convert implementation of IValueConverter will look something like this:
您需要实现IValueConverter接口,将 uri 转换为图像。您的 IValueConverter 的 Convert 实现将如下所示:
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(value as string);
image.EndInit();
return image;
Then you will need to use the converter in your binding:
然后你需要在你的绑定中使用转换器:
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding Path=ImagePath, Converter=...}" />
</Image.Source>
</Image>
回答by Luis Cantero
The problem with the answer that was chosen here is that when navigating back and forth, the converter will get triggered every time the page is shown.
此处选择的答案的问题在于,在来回导航时,每次显示页面时都会触发转换器。
This causes new file handles to be created continuously and will block any attempt to delete the file because it is still in use. This can be verified by using Process Explorer.
这会导致不断创建新的文件句柄,并会阻止任何删除文件的尝试,因为它仍在使用中。这可以通过使用 Process Explorer 进行验证。
If the image file might be deleted at some point, a converter such as this might be used: using XAML to bind to a System.Drawing.Image into a System.Windows.Image control
如果图像文件可能在某个时候被删除,则可能会使用这样的转换器: 使用 XAML 将 System.Drawing.Image 绑定到 System.Windows.Image 控件
The disadvantage with this memory stream method is that the image(s) get loaded and decoded every time and no caching can take place: "To prevent images from being decoded more than once, assign the Image.Source property from an Uri rather than using memory streams" Source: "Performance tips for Windows Store apps using XAML"
这种内存流方法的缺点是每次都加载和解码图像,并且不会发生缓存:“为了防止图像被多次解码,请从 Uri 分配 Image.Source 属性,而不是使用内存流”来源:“使用 XAML 的 Windows 应用商店应用的性能提示”
To solve the performance issue, the repository pattern can be used to provide a caching layer. The caching could take place in memory, which may cause memory issues, or as thumbnail files that reside in a temp folder that can be cleared when the app exits.
为了解决性能问题,可以使用存储库模式来提供缓存层。缓存可能发生在内存中,这可能会导致内存问题,或者作为驻留在临时文件夹中的缩略图文件,可以在应用程序退出时清除。
回答by Karthik Krishna Baiju
you may use
你可以使用
ImageSourceConverter class
ImageSourceConverter 类
to get what you want
得到你想要的
img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");

