2013-01-17 76 views
3

我有一個問題,與我的WPF應用程序。 我想在我的gridview中用我的viewmodel中的image屬性綁定一個圖像域。異步數據綁定的圖像,導致交叉線程異常

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

這是沒有問題的,如果我不使用IsAsync。 但是,我想做異步,因爲它是很多圖像加載,它需要從web服務加載它們。

Image屬性的代碼是this,它只是調用一個處理程序dll,它調用webservice。

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時,它處理線程本身。我需要以某種方式在數據綁定中調用? 如果是這樣,我該怎麼做?

+0

你可以添加你的圖片屬性的代碼? – mathieu

+0

@mathieu,當然。 – Nicolai

+0

'BitmapSource'源自'Freezable'。如果您在創建位圖後不打算更改位圖,則可以簡單地將其「凍結」。然後任何線程都可以訪問它。 – Niki

回答

5

IsAsync意味着綁定屬性將從另一個線程訪問,因此請確保您創建的任何內容都可以以跨線程方式使用。綁定的最後一步將始終發生在主線程上。

WPF中的幾乎所有類都繼承自DispatcherObject,它基本上是在創建時將對象鏈接到當前線程。代碼中的BitmapSource在另一個線程上創建,然後無法在主UI線程上使用。

然而,從FreezableBitmapSource繼承:只需在返回之前調用您BitmapSourceFreeze方法,使之不可改變的,可從任何線程。

0

如果您在單獨的線程上訪問映像並且不使用IsAsync,那麼該怎麼辦。像

public BitmapSource Image 
    { 
     get 
     { 
      return image ?? (Task.Factory.StartNew(() => image = ImageHandler.GetDefaultImages(new[] { ItemNumber }, 160, 160)[0].BitmapSource());) 
     } 
    }