【发布时间】:2017-05-16 22:38:53
【问题描述】:
我有一个ListView 绑定到一个ObservableCollection。这个 ListView 使用一个 ItemTemplate,它只包含一个 Image 控件,它的 Source 属性绑定到一个 URL 字符串。
对于某些 URL,图像无法加载,因为远程服务器会返回“Forbidden (403)” - 这可以通过向获取图像的 HTTP 请求添加特定标头来解决,但是问题是我不知道应该如何修改上述请求。
我尝试了两种不同的方法:
- 创建
IValueConverter对象。我会自己获取 URL 并获取图像数据 - 将其放入MemoryStream并使用流初始化BitmapImage对象并将其返回给 Image 控件。事实证明,这种方法非常缓慢,并且阻塞了 UI 线程。 - 创建要绑定的新属性将返回包含图像数据的字节数组。此数据将在第一次使用任务调用时延迟初始化。当数据完成下载时,
PropertyChanged事件将被触发,这将在视觉上更新图像。这种方法不会阻塞 UI 线程,但由于某种原因速度极慢。
我想知道两件事:
为什么我的方法明显变慢了?
如何直接修改图像控件从远程服务器获取图像的方式,而不会对性能/速度造成太大影响?
考虑以下示例:
public byte[] ImageThumbnail
{
get
{
if (img == null) img = GetImage(ImageUrls.Thumbnail);
return img;
}
}
public byte[] GetImage(string url) {
HttpClient client = new HttpClient();
// add some headers
return client.GetByteArrayAsync(url).Result;
}
图像将绑定到“ImageThumbnail”,并将 IsAsync 设置为 True。在这种情况下,与仅将 URL 直接绑定到图像源相比,图像的下载速度要慢得多。
【问题讨论】:
-
“为什么我的方法明显变慢了?”除非您向我们展示您的代码,否则没有人能说出来。作为提示,您可能应该使用异步绑定(通过设置其 IsAsync 属性)。直接绑定到在 Binding 调用属性 getter 时(异步)创建的 ImageSource 属性。不要使用绑定转换器,因为它不会被异步调用。
-
是的,我知道为什么绑定转换器不起作用,只是想也许有一种异步的方式来实现它。我已经尝试过使用异步绑定 - 我在问题中添加了一个示例。