Forum: PC-Programmierung C# Event wenn sich eine Class Variable ändert


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Tom (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen ich hab mal eine Frage zu C#.

Mein Main Programm erstellt eine Klasse welche wiederum einen eigenen 
Task aufmacht. Der Task ändert bei bestimmten Ereignissen eine Variable 
in der Klasse. Soweit so gut. Nun wollte ich aus der Klasse eine 
Funktion des Hauptprogramm aufrufen um die Anzeige zu ändern, leider hab 
ich keinen Plan wie das geht und wollte mal fragen ob ihr mir einen Tipp 
geben könnt (weiß leider auch nicht wonach ich genau googlen sollte :| )

Danke und VG Tom

von Werkstudent (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich hoffe dein Programm erstellt ein Objekt einer Klasse ;) Wenn der 
Task eine Klassenvariable ändert, dann integrierst du die Überwachung 
entweder in die Klasse mit rein oder du erstellst eine globale 
Überwachung dieser Variable. Gibt es nur 1 Objekt dieser Klasse, dann 
könntest du sie als static-Variable deklarieren (für Punkt 2 geeignet). 
Wenn mehrere unabhängige Objekte erstellt werden, so würde ich es in die 
Klasse selbst integrieren. Wie ändert der Task die Variable? Direkt in 
dieser oder ähnlicher Form: class_object.var = XX; oder ruft der Task 
eine Methode der Klasse auf, die so sein könnte: 
class_object.changeVar(newXX);
Ich würde es über eine Methode realisieren und dann in der Methode diese 
Überprüfung reinsetzen

Um aus der Klasse heraus Methoden des Hauptprogrammes anzusteuern 
könntest du die Methoden public machen oder einfach static mit 
Parameterübergabe:
hauptklasse.machewas(param);

hier macht dann machewas(param) genau das was du ändern möchtest und 
erhält die Parameter, die geändert werden sollen

von Tom (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Werkstudent,

ich habe eine Klasse erstellt welche in meinen Programm als neue instanz 
erstellt wird:
1
SW_Simulation_Class sw_Simulation_Class = new SW_Simulation_Class ();

in der Klasse nutze ich eine Timer, welcher bei einem Tick Variablen 
ändert (bzw nicht jedesmal). Dazu hab ich eine Funktion in der Klasse 
welche die Änderung anzeigt
1
protected void OnChanged(EventArgs ea)

in meinem Hauptprogramm hab ich einen EventHandler eingebaut:
1
sw_Simulation_Class .Changed += new EventHandler(SimulationChanged);

und eine Funktion erstellt:
1
  public void SimulationChanged(Object objSender, EventArgs e)
2
        {
3
           Ch1ProgressBar.Value = 44;
4
        }

und bei dem Aufruf "Ch1ProgressBar.Value = 44;" sturzt mein program 
immer ab und ich bekomme eine Error Meldung (siehe Bild)

Danke für eure Hilf,

VG Tom

von Tom (Gast)


Bewertung
0 lesenswert
nicht lesenswert
mit
1
            try
2
            {
3
                Ch1ProgressBar.Value = 44; 
4
            }
5
            catch (Exception exc)
6
            {
7
                Console.WriteLine(Convert.ToString(exc));
8
            }

bekomme ich folgende Fehlermeldung:
1
System.InvalidOperationException: Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement Ch1ProgressBar erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
2
   bei System.Windows.Forms.Control.get_Handle()
3
   bei System.Windows.Forms.Control.SendMessage(Int32 msg, Int32 wparam, Int32 lparam)
4
   bei System.Windows.Forms.ProgressBar.UpdatePos()
5
   bei System.Windows.Forms.ProgressBar.set_Value(Int32 value)
6
   bei SW.infoGroupBox.SimulationChanged(Object objSender, EventArgs e) in C:\Users\**** \SW Form1.cs:Zeile 77.
7
Der Thread 0x29e0 hat mit Code 0 (0x0) geendet.

gibt es da eine Lösung?

Tom

von Sebastian E. (sbe_15)


Bewertung
0 lesenswert
nicht lesenswert

von Tom (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe eine Lösung gefunden
1
public void SimulationChanged(Object objSender, EventArgs e)
2
{
3
  try
4
  {
5
    int Ch1ValueInt = bravo_SW_Simulation_Code.Ch1;
6
    int Ch2ValueInt = bravo_SW_Simulation_Code.Ch2;
7
    // ... etc ...
8
9
    Ch1ProgressBar.Invoke(new Action(() =>
10
    {
11
      Ch1ProgressBar.Value = Ch1ValueInt;
12
    }));
13
  }
14
  catch (Exception exc)
15
  {
16
    Console.WriteLine(Convert.ToString(exc));
17
  }
18
}

gibzt es noch eine elegante Lösung wenn ich gleich mehrere Änderungen 
z.B. auch
1
 Ch2ProgressBar.Value = Ch2ValueInt;
etc. ändern möchte?

Danke und VG

Tom

von Tom (Gast)


Bewertung
0 lesenswert
nicht lesenswert
@ Sebastian E.: Danke schau ich mir gleich an, ich hab auch etwas 
ähnliches gefunden ;)

von Dirk (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Du hast nicht geschrieben, ob du WinForms meinst oder WPF. In WPF ist es 
relativ einfach in der Verbindung von MVVM pattern.

von Sebastian E. (sbe_15)


Bewertung
0 lesenswert
nicht lesenswert
@Dirk:
Es ist WinForms (siehe Namespaces im CallStack der Exception).

@Tom:
Du kannst das Invoke/BeginInvoke auch auf das übergeordnete Fenster oder 
UserControl anwenden. Per Definition "gehören" alle Controls eines 
Fensters zum selben Thread.
Kleiner Hinweis: Invoke wartet, bis der Delegate ausgeführt wurde 
(synchron) und BeginInvoke kehrt direkt zurück (asynchron).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.