Laden...

threadübergreifend von beliebigem Label den Content ändern

Erstellt von ill_son vor 13 Jahren Letzter Beitrag vor 12 Jahren 5.439 Views
I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 13 Jahren
threadübergreifend von beliebigem Label den Content ändern

Hallo,

ich habe einen SerialPort, von dessen Thread aus ich im Window verschiedene Labels ändern möchte. Ich hatte das Problem damals schon einmal mit Windows-Forms und hatte es so gelöst:


delegate void SetTextDelegateType(Control control, string content);
SetTextDelegateType setTextDelegate = (a, b) => a.Text = b;
private void SetText(Control control, string text)
{
  if (control.InvokeRequired)
  {
    control.Invoke(setTextDelegate, new object[] { control, text });
  }
  else control.Text = text;
}

Nun habe das gleiche Problem in WPF und hatte mir mit Hilfe der Beispiele hier das Ganze so abgeändert:


delegate void SetContentDelegateType(Label label, string content);
SetContentDelegateType setContentDelegate = (a, b) => a.Content = b;
private void SetContent(Label label, string content)
{
  if (!label.Dispatcher.CheckAccess())
  {
    label.Dispatcher.Invoke(setContentDelegate, new object[] { label, content });
  }
  else label.Content = content;
}

Allerdings läuft das nicht so einfach, wie ich befürchtet hatte, weil Invoke bei Invoke die Argumente nicht passen.
Wie lässt sich das in WPF lösen. Wie gesagt, ich möchte das Label und den zu ändernden Content übergeben können.

Grüße...

Final no hay nada más

S
902 Beiträge seit 2007
vor 13 Jahren

Allerdings läuft das nicht so einfach, wie ich befürchtet hatte, weil Invoke bei Invoke die Argumente nicht passen.
Grüße...

dann gibt VS ja sicher auch einen Fehler, welcher Parameter wo nicht passt?

mfg
serial

I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 13 Jahren

ja, gibt es:

Die beste Übereinstimmung für die überladene System.Windows.Threading.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority, System.Delegate)-Methode hat einige ungültige Argumente.

1-Argument: kann nicht von "HHLA.mySerial.SetContentDelegateType" in "System.Windows.Threading.DispatcherPriority" konvertiert werden.

2-Argument: kann nicht von "object[]" in "System.Delegate" konvertiert werden.

Ich hab's jetzt mal so versucht:


label.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, setContentDelegate, new object[] { label, content });

Erstmal ohne Fehlermeldung beim Compilieren.
Mal sehen, ob's auch läuft.

Grüße...

Final no hay nada más

I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 13 Jahren

Eine Frage zu der Thematik hätte ich noch.

Die Klasse der seriellen Schnittstelle habe ich von SerialPort abgeleitet und noch ein paar Erweiterungen vorgenommen. Unteranderem einen Timer, die Schnittstelle pollt. Wenn ich nun etwas empfangen habe, soll das im Label, welches sich im Hauptfenster befindet angezeigt werden. Allerdings bietet mir die Intellisense die Controls nicht an und auch FindName funktioniert nicht (Fehlermeldung: Name im Kontext nicht vorhanden).

Danke und Gruß...

Final no hay nada más

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo,

Allerdings bietet mir die Intellisense die Controls nicht an und auch FindName funktioniert nicht (Fehlermeldung: Name im Kontext nicht vorhanden).

Von wo aus versucht du auf die GUI zuzugreifen?
Wenn du das direkt von deiner SerialKlasse aus machen willst dann funktioniert das so einfach nicht => und das ist auch gut so 😃

Guck mal hier: [FAQ] Kommunikation von 2 Forms
Du kannst in deiner SerialPort-Klasse ein Event schmeißen auf welches deine GUI dann reagiert und die Daten anzeigt.

Bitte beachte: [Hinweis] Wie poste ich richtig? 1.1 und 1.1.1

Gruss
Michael

I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 13 Jahren

Ja, ich hatte versucht, aus der Serial-Klasse auf die Label zuzugreifen (dumm)
Sorry, hatte nicht gedacht, dass das so basic ist.

Danke und Grüße...

Final no hay nada más

I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 13 Jahren

Hallo,

ich möchte die Thematik nocheinmal aufgreifen, weil ich nicht so recht weiterkomme.
Ich habe versucht, eine vorhandene Lösung für Windows Forms in WPF umzuschreiben.

alt:


delegate void SetTextDelegateType(Control control, string text);
SetTextDelegateType setTextDelegate = (a, b) => a.Text = b;
private void SetText(Control control, string text)
{
   if (control.InvokeRequired)
   {
      control.Invoke(setTextDelegate, new object[] { control, text })
   }
   else control.Text = text;
}

neu:


delegate void SetContentDelegateType(Label label, string content);
SetContentDelegateType setContentDelegate = (a, b) => a.Content = b;
private void SetContent(Label myLabel, string myContent)
{
   if (!myLabel.Dispatcher.CheckAccess())
   {
     myLabel.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,   setContentDelegate, new object[] { myLabel, myContent });
   }
   else myLabel.Content = myContent;
}

Ich bekomme immer eine TargetParameterCountException, irgendwo stimmt die Parameteranzahl nicht, aber an welcher Stelle?
Bitte helft mir kurz weiter.

Danke und Grüße...

Final no hay nada más

U
1.688 Beiträge seit 2007
vor 13 Jahren

Hallo,

Ich bekomme immer eine TargetParameterCountException, irgendwo stimmt die Parameteranzahl nicht, aber an welcher Stelle?

Meinst Du nicht, dass es eine gute Idee wäre, mal in die Dokumentation zu schauen?
Dispatcher.Invoke-Methode

I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 13 Jahren

Hallo ujr,

danke für den Hinweis mit der Doku. Mir ist aufgefallen, dass obwohl ich im Projekt .Net 3.5 eingestellt habe, nur sechs Möglichkeiten zur Überladung angezeigt bekomme, und das sind die, die in der der Doku bei .NET 3.0 aufgeführt sind. Deshalb wohl auch die Exception. Weißt Du, woran das liegen kann?

Grüße...

Final no hay nada más

1.378 Beiträge seit 2006
vor 12 Jahren

Du rufst die Methode mit nur einem Argument auf: Dispatcher.Invoke-Methode (DispatcherPriority, Delegate, Object),
obwohl du eigentlich die Variante mit beliebig vielen Argumenten aufrufen willst: Dispatcher.Invoke (DispatcherPriority, Delegate, Object, Object[])

Der Fehler mit der Parameteranzahl kommt auch daher, dass du als Argument(e) ein Object-Array übergeben hast.

Lg, XXX

//Edit: Die Überladungen sind aber auch ziemlich dumm gewählt mMn.