3

WPFアプリケーションに問題があります。グリッドビューの画像フィールドを、ビューモデルのimageプロパティとデータバインドしようとしています。

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

IsAsyncを使用しなくても、これは問題ありません。ただし、ロードする画像が多く、Webサービスからロードする必要があるため、非同期で実行したいと思います。

Imageプロパティのコードはこれです。これは、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に設定されている場合、WPFはスレッド自体を処理すると思いました。データバインディングで、どういうわけか呼び出す必要がありますか?もしそうなら、一体どうやってこれを行うのですか?

4

2 に答える 2

6

IsAsyncバインドされたプロパティは別のスレッドからアクセスされることを意味するため、作成するものはすべてクロススレッド方式で使用できることを確認してください。バインディングの最終ステップは常にメインスレッドで行われます。

WPFのほとんどすべてのクラスは、から継承しDispatcherObjectます。これは、基本的に、オブジェクトの作成時にオブジェクトを現在のスレッドに「リンク」します。コード内のBitmapSourceは別のスレッドで作成されているため、メインUIスレッドでは使用できません。

ただし、BitmapSource継承元:は、戻る前にメソッドをFreezable呼び出すだけで、どのスレッドからでも不変で使用できるようになります。FreezeBitmapSource

于 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 に答える