views:

14

answers:

1

I have a datagrid with a template column. The template has an image:

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

The grid scrolls very slowly because the ProductImage lazilly loads a private bitmapimage object as the user scrolls the grid. I was thinking of using another thread to load the private variable (behind the ProductImage property). I'm getting into trouble with my code because of various reasons...one exception was I can only update UI on the STA thread and another was a dependency source can't be in a different thread than the dependency sink (?)

I can't think of a good way to do this. The code for the grid looks something like this with a failed attempt at the backgroundworker:

        var productVMList = GetProducts();

        _window.ReceivingBatchProductsGrid.ItemsSource = productVMList;

        var setProductImageWorker = new BackgroundWorker();

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

And here is DoWork:

var products = (ObservableCollection)e.Argument;

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

Any thoughts?

+1  A: 

Normally, dependency objects can only be used on the thread that created them. However, the ones that inherit from Freezable (like ImageSource for instance) can be used from another thread, as long as they are frozen. So when you create your ImageSource objects on another thread, you just need to call Freeze on them before you send them to the UI, and it should work fine.

An easy way to make the images load asynchronously is to use the Binding.IsAsync property:

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

That way you don't need to worry about creating a new thread and updating the target property when the image is loaded, it's handled automatically by WPF.

Thomas Levesque