我的WPF应用程序出了问题。 我正在尝试使用viewmodel中的image属性在我的gridview中对图像字段进行数据绑定。
<DataGridTemplateColumn Header="Image" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=Image, IsAsync=True}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
如果我不使用IsAsync,这没问题。 但是,我想做异步,因为它需要加载大量图像,并且需要从Web服务加载它们。
Image属性的代码是this,它只调用一个调用web服务的处理程序dll。
public BitmapSource Image
{
get { return image ?? (image = ImageHandler.GetDefaultImages(new[] {ItemNumber},160,160)[0].BitmapSource()); }
}
但是,只要我添加IsAsync = true,我就会在表单加载后得到以下异常:
The calling thread cannot access this object because a different thread owns it.
我是WPF的新手,我有点假设,当异步设置为true时,它处理了线程本身。在数据绑定中是否需要以某种方式调用? 如果是这样,我该怎么做呢?
答案 0 :(得分:6)
IsAsync
表示将从另一个线程访问绑定属性,因此请确保您创建的任何内容都可以以跨线程方式使用。绑定的最后一步将始终发生在主线程上。
WPF中的几乎所有类都继承自DispatcherObject
,它基本上将对象“链接”到当前线程创建时。代码中的BitmapSource
是在另一个线程上创建的,然后无法在主UI线程上使用。
但是,BitmapSource
继承自Freezable
:只需在返回之前调用BitmapSource
上的Freeze
方法,以使其在任何线程中都不可变且可用。
答案 1 :(得分:0)
如果您在单独的线程上访问图像并且不使用IsAsync,那该怎么办?像
这样的东西public BitmapSource Image
{
get
{
return image ?? (Task.Factory.StartNew(() => image = ImageHandler.GetDefaultImages(new[] { ItemNumber }, 160, 160)[0].BitmapSource());)
}
}