2009-08-04 54 views
0

Ich verwende das MVVM-Muster, um eine WPF-Anwendung zu entwickeln.Zugriff auf ein WPF-Objekt im Dispatcher?

Die App lädt ein Captcha-Bild vom Server und weist es einem Image im WPF-Formular zu, wenn es fertig ist. Ich verwende einen Background für mich das Einfädeln zu tun, wie folgt:

Wenn das Fenster geladen wird, wird die folgende genannt:

BackgroundWorker _bgWorker = new BackgroundWorker(); 

_bgWorker.DoWork += GetCaptchaImage; 
_bgWorker.RunWorkerAsync(); 

Die GetCaptchaImage Funktion ziemlich einfach ist, das Laden eines Bildes in einem anderen Thread:

BitmapSource _tempBitmap = GetCaptchaFromServer(); 

ich muss wissen, wie die Dispatcher an Invoke diese Image zu meinem Fenster der Bildquelle zuzuweisen, Zeit rufe ich die Dispatcher nach dem _tempBitmap Laden wie folgt:

Application.Current.Dispatcher.Invoke(
new Action(() => CaptchaBitmap = _tempBitmap)); 

Wo CaptchaBitmap meine Bildquelle datengebundene wird.

Wenn ich dies tue, wird jedoch eine InvalidOperationException ausgelöst, und jeder Verweis auf _tempBitmap gibt einen Fehler im Thread GUI zurück. Ich weiß es, weil ich es vom Dispatcher GUI-Thread zugreift, wenn es in einem BackgroundWorker-Thread erstellt wurde, aber wie komme ich um es herum?

Hilfe wäre sehr dankbar! :)

Antwort

0

Nur aus Neugier. Warum machen Sie nicht das gesamte Abrufen und Festlegen des Bildes im Dispatcher-Thread statt der BackgroundWorker-Klasse?

Dispatcher.Invoke(DispatcherPriority.Background, 
    new Action(() => { CaptchaBitmap = GetCaptchaFromServer(); }) 
); 
5

Gerade BitmapSource.Freeze rufen vor Dispatcher.Invoke Aufruf

BitmapSource _tempBitmap = GetCaptchaFromServer(); 
_tempBitmap.Freeze(); 
Application.Current.Dispatcher.Invoke(
new Action(() => CaptchaBitmap = _tempBitmap)); 

Alle WPF-Objekte können nur aus dem Thread zugegriffen werden, die sie geschaffen haben, sind die Ausnahmen Dispatcher (aus offensichtlichen Gründen) und Freezable nach Sie rufen die Freeze-Methode auf.

Nach dem Aufruf von Freeze kann das Objekt von jedem Thread (aber kann nicht geändert werden) zugegriffen werden, zum Glück für Sie BitmapSource erbt von Freezable.

+0

Ich habe meine Haare für die letzte Stunde über dieses Problem ausreißen. Tausend Dank! –

0

@Arcturus, Aus meiner Erfahrung, wenn Sie das tun, werden Sie keine UI-Reaktionsfähigkeit erhalten, bis der Download vom Server abgeschlossen ist ... weil Sie eigentlich den UI-Thread unterbrechen und DANN das Zeug herunterladen ... Ich mache diesen Fehler in ein paar meiner Projs und frage mich, warum die UI nicht reagiert ....

+0

Ja, das stimmt. Deshalb mache ich normalerweise die Arbeit im Hintergrund-Thread, so dass der UI-Thread die meisten Aufmerksamkeiten erhält und ständig aktualisiert. – Arcturus