none
WPF: Timer verwenden RRS feed

  • Frage

  • Hallo Forum,

    ich benötige in meiner WPF-Anwendung einen Timer und bin auf den "Threading.DispatcherTimer" gestoßen. Bei diesen finde ich jedoch keine Eigenschaft die es ermöglicht das gesetzte Intervall nur einmal zu durchlaufen. Die Methode Timer.Stop() hilft mir nicht da ich sie zu einen Zeitpunkt setzen müsste, die den Timer vor der ersten Aktivierung stoppt.

    Vielleicht verwende ich den falschen Timer-Typ? Nachfolgend der logische Ablauf,

    lg heinz

                            
    private Sub BilderMarkieren()
    ....
    
    Dim m_Timer1 = New Threading.DispatcherTimer
                            AddHandler m_Timer1.Tick, AddressOf Timer1_Tick
                            m_Timer1.Interval = New TimeSpan(0, 0, 1)
                            m_Timer1.Start()
                            m_KlickStatus = 0                   'Aktion abgeschloßen
                            'm_Timer1.Stop()
    ....
    End Sub
    
            Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs)
                
                EinBildEntmarkieren(m_KlickCol1, m_KlickRow1, m_KlickZellNr1)
                EinBildEntmarkieren(m_KlickCol2, m_KlickRow2, m_KlickZellNr2)
            End Sub
    

    Mittwoch, 27. März 2013 09:50

Antworten

  • Hallo Forum,

    mein Problem lag in einer falschen Deklarierung des Timers. Ich habe den Timer im globalen Bereich nicht als "shared" definiert. Und das löste eine Reihe von falschen Schlußfolgerungen aus. Da nun der Timer global sichtbar ist, kann ich ihn auch im Event-Teil (wie dargestellt) stoppen.

    Sorry für eure Mühe und lg heinz

    • Als Antwort markiert Heinz9 Mittwoch, 27. März 2013 13:07
    Mittwoch, 27. März 2013 13:06

Alle Antworten

  • Hi Heinz.

    Ich bin jetzt kein WPF-Spezi, aber das klingt für mich weniger nach einem Problem des Programmierdialekts als nach einem Problem der Ablauflogik.

    Man könnte das z.B. über eine globale Prüfvariable lösen.

    Oder du könntest dir auch einen MyTimer ableiten, dem du noch einen "Aufruf-Count" verpasst, den du immer hochzählst, sobald der MyTimer aktiv wird.

    Alternativ könntest du ja eine Art "Timer-Queue" programmieren. Du kannst die zu erledigenden Aufgaben, die im Timer passieren sollen (hier offenbar das deaktivieren von irgendwelchen Bildern an irgendwelchen Koordinaten), in die Queue hinzufügen und den Timer aktivieren. Der Timer prüft dann einfach, ob noch Aufgaben aktiv sind, ob die Zeit reif ist diese zu erledigen. Und wenn alle erledigt sind, deaktiviert er sich einfach. (Hätte vielleicht auch den Vorteil, dass du einen Timer für alles brauchst und nicht - wie mir scheint - für jedes Bild einen eigenen.)

    Falls nicht klar ist, wie ich letztes meine, einfach nochmal nachhaken. Ich könnte dann ein kurzes Beispiel schreiben, wie das für eine Form aussähe. Für WPF anpassen kannst du das dann sicher selber. :-)

    LG, Dennis.

    P.S.: Wieso willst du eigentlich das Bild markieren und etwas später "zeitgesteuert" entmarkieren? Welche Absicht verfolgst du damit?


    Mittwoch, 27. März 2013 10:36
  • Hallo Dennis,

    danke für deine Lösungsansätze, aber das scheint mir alles etwas wie Notlösungen. Wenn ich in VB einen Timer verwende, habe ich die Möglichkeit einzustellen ob dieser einmal oder ewig laufen soll. Das habe ich bei diesen Timer leider nicht. Weiters muß das Konzept des Timers mit .Start(), .Stop() auch ohne Hilfszähler funktionieren sonst ist es sinnlos. Eine logische Möglichkeit wäre eine globale Definition des Timers und dann ein .Stop() in der Timer.Tick Methode selbst. Das gelingt mir allerdings nicht, da die Definition des Handler im Code dann nicht funktioniert.

    Ich glaube, dass ich irgendetwas syntaktisch falsch mache.

    Danke und lg heinz

    Mittwoch, 27. März 2013 10:58
  • Hallo Heinz,
    ist es möglich den Timer durch ein Sleep zu setzten. Du suchst doch nur eine Pause von 1 Sekunde?
    Die andere Option wäre den Timer, wie man das halt so macht, auszuschalten wenn der Tick feuert.
    Was ist mit dem setzten von m_timer1.Stop() im Event?
    HTH

    Grüße Alexander

    Mittwoch, 27. März 2013 10:58
  • Hallo Alexander,

    wenn ich den timer.Stop() im Event setzen könnte, würde es wohl funktionieren. Aber dann müsste ich den Timer selbst im globalen Teil der Klasse definieren. Wenn ich das tu, dann bringt mir die Handler-definition (AddHandler m_Timer1.Tick, AddressOf Timer1_Tick) einen Fehler (er kennt .Tick nicht). Fehlerfrei? gehts nur innerhalb einer Funktion.

    lg heinz

    Mittwoch, 27. März 2013 11:10
  • Hi,
    nimm doch einen üblichen Timer, z.B. einen System.Timer, den Du bei Notwendigkeit einfach wieder ausschaltest.
     
    --
    Peter Fleischer
    Mittwoch, 27. März 2013 12:31
  • Hallo Peter,

    das wollte ich ursprünglich auch. Da bekam ich aber Probleme beim Aufrufen von Funktionen aus der Event-Funktion ( Variable gehört einen anderen Tread ). Darum bin ich auf diesen Timer gekommen,

    lg heinz

    Mittwoch, 27. März 2013 12:59
  • Hallo Forum,

    mein Problem lag in einer falschen Deklarierung des Timers. Ich habe den Timer im globalen Bereich nicht als "shared" definiert. Und das löste eine Reihe von falschen Schlußfolgerungen aus. Da nun der Timer global sichtbar ist, kann ich ihn auch im Event-Teil (wie dargestellt) stoppen.

    Sorry für eure Mühe und lg heinz

    • Als Antwort markiert Heinz9 Mittwoch, 27. März 2013 13:07
    Mittwoch, 27. März 2013 13:06
  • Hi,
    für den Zugriff aus der Timer-Ereignisroutine auf die nicht threadsicheren Elemente im anderen thread, z.B. Oberflächen-Steuerelemente, benötigst Du dann den Dispatcher.
     
    --
    Peter Fleischer
    Mittwoch, 27. März 2013 15:08
  • Hallo Peter,

    ja und mit dem arbeite ich jetzt zufriedenstellend ( myTimer as Threading.DispatcherTimer),

    lg heinz

    Mittwoch, 27. März 2013 15:15