WPF DataGrid - 使用BackgroundWorkerProcess更新列中的图像

时间:2010-09-17 19:13:24

标签: wpf backgroundworker

我有一个带有模板列的数据网格。模板有一个图像:

                                                        <Image HorizontalAlignment="Left" Name="ImageProduct" Stretch="None"  VerticalAlignment="Center" Grid.Row="0" Grid.Column="0"  Source="{Binding Path=ProductImage, Mode=OneWay}" RenderOptions.BitmapScalingMode="HighQuality"/>

网格滚动速度非常慢,因为当用户滚动网格时,ProductImage会加载一个私有的bitmapimage对象。我正在考虑使用另一个线程来加载私有变量(在ProductImage属性后面)。由于各种原因,我的代码遇到了麻烦...一个例外是我只能在STA线程上更新UI而另一个是依赖源不能在依赖接收器不同的线程中(?)< / p>

我想不出一个好方法。网格的代码看起来像是这样的,尝试失败的背景工作者:

        var productVMList = GetProducts();

        _window.ReceivingBatchProductsGrid.ItemsSource = productVMList;

        var setProductImageWorker = new BackgroundWorker();

        setProductImageWorker.DoWork += setProductImageWorker_DoWork;
        setProductImageWorker.RunWorkerAsync(productVMList); 

这是DoWork:

var products =(ObservableCollection)e .Argument;

        foreach (var product in products)
        {
            product.SetProductImage();
        }

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

通常,依赖项对象只能在创建它们的线程上使用。但是,从Freezable(例如ImageSource继承的那些可以从另一个线程中使用,只要它们被冻结即可。因此,当您在另一个线程上创建ImageSource个对象时,只需在将它们发送到UI之前调用Freeze,它就可以正常工作。

使图像异步加载的一种简单方法是使用Binding.IsAsync属性:

<Image ... Source="{Binding Path=ProductImage, Mode=OneWay, IsAsync=True}" ... />

这样,您无需担心在加载图像时创建新线程并更新目标属性,它将由WPF自动处理。