Timer soll Rectangle neu füllen
-
Hallo,
ich versuche gerade eine eigene kleine progressbar zu erstellen.
Folgender Code:class DTimer { private Timer timer; private int bar_status = 1; MainWindow pForm; public DTimer(MainWindow main) { this.pForm = main; } public void Start(int PeriodInSeconds) { this.timer = new System.Threading.Timer(timer_Task, null, 0, PeriodInSeconds*1000); } public void Stop() { timer.Dispose(); } private void timer_Task(object State) { pForm.rec1.Fill = System.Windows.Media.Brushes.White; //ZEILE X Console.WriteLine(bar_status); bar_status++; if (bar_status > 5) bar_status = 1; } }
Im Konstruktor übergebe ich MainWindow, damit ich auf das Rectangle zugreifen kann. Wenn ich im selbigen Konstruktor die Zeile X schreibe, also quasi die Farbe des Objekts rec1 ändere, funktioniert das auch.
Aber wenn ich in der Methode "timer_Task" auf ein Objekt in MainWindow zugreife, also die Füllfarbe änder, dann schließt das Programm automatisch.
Sobald ich aber Die ZEILE X auskommentiere funktioniert die Hochzählung (Ausgabe Console von bar_status) nach starten des Timers.
Wo liegt mein Fehler in der WPF Anwendung?
Gruß Gustl
-
Erstens: Übergebe bitte keine Windows an eine andere Klasse.
Zweitens: Zum eigentlichen Problem, du arbeitest mit dem System.Threading.Timer, das heißt du musst Zugriffe auf das GUI synchronisieren. Ich denke mal, das dein Programm sich genau deshalb schließt: Es kommt in einem extra Thread (timer_Task) zu einer Exception.
-
Hallo,
Erstens: Übergebe bitte keine Windows an eine andere Klasse.
Macht man das wohl nicht? Warum nicht? Wie kann ich denn sonst von einer Klasse auf die WindwosMain zugreifen?
das heißt du musst Zugriffe auf das GUI synchronisieren.
Dann muss ich die repaint()? von der main mit meinem timer synchronisieren?
Wo muss ich da ansetzen damit ich diese synchron bekomme?Danke.
-
Gustl schrieb:
Macht man das wohl nicht? Warum nicht? Wie kann ich denn sonst von einer Klasse auf die WindwosMain zugreifen?
Ich hätte es jetzt nicht so strikt formuliert, aber man hat in WPF grundsätzlich andere Konzepte um sowas zu erreichen. Das Ziel dabei ist immer, dass man eine lose Kopplung und eine hohe Kohäsion hat. Das vereinfacht im Gesamten die Wartung.
Um dir zu sagen, was du da verwenden könntest, müsste man mehr darüber erfahren, was du genau machen willst.
Gustl schrieb:
Dann muss ich die repaint()? von der main mit meinem timer synchronisieren?
Wo muss ich da ansetzen damit ich diese synchron bekomme?Am besten verwendest du einen Timer, welcher in der Nachrichtenschleife des GUIs läuft. Die Events werden somit gleich im GUI Thread ausgelöst. Für WPF gibt es dazu den
DispatcherTimer
.Grüssli
-
Hi,
danke, mit dem DispatcherTimer hat es funktioniert.
Gruß