Laden...

Leidiges Thema Delegates (Übergabe von ImageSource)

Erstellt von guro vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.012 Views
G
guro Themenstarter:in
5 Beiträge seit 2012
vor 11 Jahren
Leidiges Thema Delegates (Übergabe von ImageSource)

Hallo zusammen,

ich bin neu im Forum und mache gerade meine ersten Schritte mit WPF (Davor nur c# mit WinForms).

Delegates und sowas hab ich nie groß verstanden und gebraucht weil man in WinForms ja per CheckForIllegales... = False das problem schnell umgehen konnte 😉

Nun also zu meinem Problem:

ich habe meine Mainwindow-Klasse, in der eine selbstgeschrieben Klasse (cHandler) initialisiert wird.
in der Klasse cHandler brauche ich Zugriff auf ein paar Controls aus dem Mainwindow, weswegen ich im Konstruktor von cHandler mir meine Mainwindow-Klasse mit übergebe. Das klappt ja alles, ich lese und schreibe ohne Probleme in eine Combobox (Warum geht das?!)

Jetzt habe ich in cHandler einen Event der ein neues Bild bekommt bei Aufruf (Leider noch System.Drawing.Bitmap, welche noch nach ImageSource umgewandelt wird).

Wie bekomme ich dieses Bild bzw. das ImageSource jetzt auf mein <Image>-Control.Source ohne ständig "InvalidOperationsException: The calling thread cannot access this object because a different thread owns it. " zu bekommen?

So weit ich das verstanden habe bräuchte ich jetzt in cHandler ne delegate, die von meinem Event aufgerufen wird und dann das bild übergibt, oder? Leider scheitern alle meine Versuche.

Würde mich über jede Hilfe freuen! Habe schon Dispatcher.Invoke probiert und echte Delegates, ohne erfolg 😦

Danke für jede Hilfe!!! Vielleicht check ich dann langsam mal das Konzept der Delegates 😉

Viele Grüße
guro

3.430 Beiträge seit 2007
vor 11 Jahren

Hallo guro,

willkommen bei myCSharp.de

in der Klasse cHandler brauche ich Zugriff auf ein paar Controls aus dem Mainwindow, weswegen ich im Konstruktor von cHandler mir meine Mainwindow-Klasse mit übergebe.

Das ist Design-Technisch aber nicht so gut. Denn du hast da Abhängigkeiten zwischen deinen cHandler und dem MainWindow die so nicht sein sollten.
In der Regel sollte der cHandler das MainWindow gar nicht kennen sondern nur die Daten über bestimmte Properties bereitstellen welche dann im MainWindow über DataBinding verbunden werden.
Dadurch sparst du dir viele Probleme und dein Code wird viel schöner 😃
Wie DataBinding funktioniert findest du unter anderen hier: WPF - DataBinding
Wenn du ein bisschen suchst dann findest du auch sonst noch massenweise Beispiel zum DataBinding etc.

Wie bekomme ich dieses Bild bzw. das ImageSource jetzt auf mein <Image>-Control.Source ohne ständig "InvalidOperationsException: The calling thread cannot access this object because a different thread owns it. " zu bekommen?

Siehe: [FAQ] Warum blockiert mein GUI? bzw. [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)
Du musst sicherstellen dass du die ImageSource nur im gleichen Thread zuweist wie das Image erstellt wurde (also im GUI Thread).
Wie das funktioniert findest du in den Links.

Grüße
Michael

G
guro Themenstarter:in
5 Beiträge seit 2012
vor 11 Jahren

Hallo Michael,

danke erst mal für dein Posting.

Mittlerweile bin ich auf eine Lösung gekommen, meine Delegate mit Dispatcher.Invoke hat funktioniert, das problem war hier eher das <image>-Element, bzw. das ImageSource-Objekt.

Für alle die auch das Problem haben: Man muss das ImageSource object einfrieren, dann wird es vom ersteller-thread freigegeben. Umsetzung: ganz simples

isImage.Freeze();

Ärgerlich das sowas einen 4h rumdoktorn kostet 😦

Das mit den Datenbinding schau ich mir an, mir gefällt die Lösung mit dem Übergeben des ganzen Fensters auch noch nicht so 😄

G
guro Themenstarter:in
5 Beiträge seit 2012
vor 11 Jahren

Ist doch nochmal ein Problem aufgetaucht:

cHandler muss 2 Comboboxen befüllen und auch den SelectedIndex auslesen, dann noch 2 Labels befüllen und eben dieses ImageSource übergeben. Wie geh ich da am sinnvollsten mit DataBinding vor?

3.430 Beiträge seit 2007
vor 11 Jahren

Hallo,

dazu muss dein cHandler einfach die nötigen Properties bereitstellen.
D.h. der hat zwei Listen für die ComboBoxen, dann noch zwei Strings für die Labels sowie die ImageSource

Im Xaml bindest du dann über das DataBinding an die einzelnen Properties

PS: als Listen verwendest du am Besten die ObservableCollection weil diese schon selbst über den CollectionView den SelectedIndex etc verwalten kann

Grüße
Michael