C# eigene DispatcherTimer class nutzen - Wie ? (WPF/MVVM)

antaro

Cadet 3rd Year
Registriert
Sep. 2012
Beiträge
41
Hallo Leute,

ich habe aus dem Web eine DispatcherTimer class, die ich gern in
meiner eigenen Applikation nutzen möchte, z.B. um ein Label zu aktualisieren.

Im MainWindowViewModel habe ich Zugriff auf Start/Stop aus DTimer.

Wie muss die Methode (EventHandler ?) aussehen, die im VM
aufgerufen wird um das Label zu aktualisieren ?
Wie wird die "Verbindung" zwischen DTimer und der Methode im VM hergestellt ?

XAML: <Label width="70" Content="{Binding StatusText}"
StatusText ist ein Property im VM.

Code:
 public class DTimer
    {
        private DispatcherTimer timer;
        public event Action<int> DoSomething;

        private int _timesCalled = 0;

        public DTimer()
        {
            timer = new DispatcherTimer();
        }

        public void Start(int PeriodInSeconds)
        {
            timer.Interval = TimeSpan.FromSeconds(PeriodInSeconds);
            timer.Tick += timer_Task;
            _timesCalled = 0;
            timer.Start();
        
        }

        public void Stop()
        {
            timer.Stop();
        }

        private void timer_Task(object sender, EventArgs e)
        {
            _timesCalled++;
            DoSomething(_timesCalled);
        }
    }
 
Wie nutze ich die Klasse DTimer ?
In meinem ViewModel (=VM) muss ich nun eine Methode schreiben,
die das Label z.B. jede Sekunde updated.

Das Beispiel von Microsoft habe ich schon durchgearbeitet.
Ich kann es aber nicht auf mein Projekt adaptieren, weil
MS alles ins MainWindow schreibt.
Muss ich einen neuen EventHandler im ViewModel schreiben ?
Die Verbindung von DTimer und der Methode, die das Label ändern soll
ist mir nicht klar ? Sorry bin noch Newbie.
 
Zuletzt bearbeitet:
Zum letzten Post: Nein du musst keine Methode schreiben die das "Label updated", das ist ja der Spaß an MVVM :evillol:. Und ich weiß aus eigener Erfahrung das die Beschreibungen zum Teil "hölle" sein können.

Aber im ViewModel geht es um die "Logik" (am besten hier mal nachlesen). Im View Bindest du eine Eigenschaft an den Context des Labels, diese musst du im ViewModel updaten nicht das Label. Was die Timer-Klasse da nun machen soll, ist aus der Beschreibung leider nicht auszulesen.

In der Regel musst du dafür sorgen dass die gebundene Eigenschaft korrekt Nachricht gibt, dass sie verändert wurde. Entweder als DependencyProperty, da ist es schon dabei oder mit dem INotifyPropertyChanged-Interface.

Ansonsten ist das vom Grund auf Lernen (gehe mal davon aus, dass es auch die erste Programmiersprache ist?!) nicht ganz einfach bei dem Konzept, weil es einfach an vielen Stellen unnötig kompliziert beschrieben wird :).

Wenn du deine Angabe noch etwas erweiterst kann ich dir ggf. auch bei einer konkreten Lösung helfen ansonsten wünsche ich weiterhin viel Erfolg beim lernen.
 
PapstRatze schrieb:
Zum letzten Post: Nein du musst keine Methode schreiben die das "Label updated", das ist ja der Spaß an MVVM :evillol:. Und ich weiß aus eigener Erfahrung das die Beschreibungen zum Teil "hölle" sein können.

Ich brauche aber schon eine Methode, in der der Wert des Property (welches an Content des Labels gebunden ist) mit einem neuen Wert gefüllt wird. Ich glaube ich habe mich etwas unklar ausgedrückt. Sorry.

Ich habe jetzt eine Lösung für das Problem gefunden:

Code:
base.DoSomething += Action<int>(MyMethod);

Mir war die Syntax für das Action-Object nicht klar. In MyMethod wird das Property StatusText (<Label Content="{Binding StatusText}/>) mit einem neuen Wert gefüllt. Den Rest erledigt die Datenbindung/Änderungsüberwachung. ;)
 
Zuletzt bearbeitet:
antaro schrieb:
Ich habe jetzt eine Lösung für das Problem gefunden:

Code:
base.DoSomething += Action<int>(MyMethod);

Mir war die Syntax für das Action-Object nicht klar.
Das ist kein Wunder, die Syntax ist auch sehr eigentümlich.
"DoSomething" ist ein Event und sollte deshalb per Konvention als "EventHandler" und nicht als "Action" definiert sein. Zudem wird in der Methode "timer_Task" "DoSomething" nicht auf null geprüft, wodurch du eine Exception bekommst wenn du dich nicht wie oben "dran gehangen" hast.

Ich persönlich würde die Klasse "DTimer" entweder komplett entfernen und den DispatcherTimer direkt im ViewModel benutzen oder einen vernünftigen Wrapper um den DispatcherTimer bauen.
 
TheCadillacMan schrieb:
Ich persönlich würde die Klasse "DTimer" entweder komplett entfernen und den DispatcherTimer direkt im ViewModel benutzen oder einen vernünftigen Wrapper um den DispatcherTimer bauen.

Hallo CadillacMan

besten Dank für deine Hinweise.
Die Prüfung auf null habe ich jetzt eingebaut.

Warum die Klasse DTimer ?
Meine Überlegung dazu ist: Ich möchte das ViewModel nicht mit Methoden überfrachten und
deshalb einiges an Funktionalität auslagern. Daraus ergibt sich aber ein Problem
(bzw. schlechter Programmierstil [imho])

Code:
DTimer : ObservableObject
MainWindowViewModel : DTimer

AddVM : MainWindowViewModel
UpdateVM : MainWindowViewModel

DTimer erbt die Änderungsüberwachung, obwohl sie dort nicht gebraucht wird.
Die ViewModels der UserControls erben volle Funktionalität und den Datenbestand komplett.
Für mich so erst mal akzeptabel, bis ich eine bessere Lösung gefunden habe.
Verbesserungsvorschläge ?


Wrapper
In dieses Thema muss ich mich erst einarbeiten. Ich versuche dann, einen Wrapper
um den DTimer zu bauen.

Gruß
antaro
 

Ähnliche Themen

Antworten
0
Aufrufe
1.397
Zurück
Oben