3

我的 WPF 应用程序有问题。我正在尝试使用我的视图模型中的图像属性在我的网格视图中对图像字段进行数据绑定。

<DataGridTemplateColumn Header="Image" IsReadOnly="True">
    <DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Image Source="{Binding Path=Image, IsAsync=True}" />
    </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

这没问题,如果我不使用 IsAsync。但是,我想异步执行,因为要加载很多图像,并且需要从 Web 服务加载它们。

Image 属性的代码是这样的,它只调用一个处理程序 dll,它调用一个 web 服务。

    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 很陌生,我有点假设,当 async 设置为 true 时,它​​自己处理线程。我是否需要在数据绑定中以某种方式调用?如果是这样,我到底该怎么做?

4

2 回答 2

6

IsAsync意味着绑定属性将从另一个线程访问,因此请确保您创建的任何内容都可以以跨线程方式使用。绑定的最后一步总是发生在主线程上。

WPF 中的几乎所有类都继承自DispatcherObject,它基本上在创建对象时将对象“链接”到当前线程。您的BitmapSource代码中的 是在另一个线程上创建的,然后不能在主 UI 线程上使用。

但是,BitmapSource继承自Freezable: 只需在返回之前调用Freeze您的方法BitmapSource,以使其不可变且可从任何线程使用。

于 2013-01-17T09:37:31.823 回答
0

如果您在单独的线程上访问图像并且不使用 IsAsync 怎么样。就像是

public BitmapSource Image
    {
        get 
        { 
            return image ?? (Task.Factory.StartNew(() => image = ImageHandler.GetDefaultImages(new[] { ItemNumber }, 160, 160)[0].BitmapSource());) 
        }
    }
于 2013-01-17T09:46:37.173 回答