Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Databinding issue with stopwatched elapsed

Tags:

c#

.net

binding

wpf

I am trying to make a class that when it starts it starts a stopwatch and all the time the elapsed time is written to a local variable Elapsed which I have a Listview that databinds to. But when I use this code the Listview just displays 00:00:00.00000001 and never changes. The class' code is:

namespace project23
{
    public class ActiveEmployee
    {
        public int EmpID { get; set; }
        public string EmpName { get; set; }
        private DateTime date;
        private BackgroundWorker worker;
        public Stopwatch sw;

        public ActiveEmployee(int empID, string empName)
        {
            date = DateTime.Now;
            worker = new BackgroundWorker();
            worker.DoWork += BackgroundWork;
            worker.WorkerReportsProgress = true;

            worker.RunWorkerAsync();
        }

        private TimeSpan elapsed;
        public TimeSpan Elapsed
        {
            get { return elapsed; }
            set
            {
                elapsed = value;
                NotifyPropertyChanged("Elapsed");
            }
        }

        private void BackgroundWork(object sender, DoWorkEventArgs args)
        {
            sw = new Stopwatch();
            sw.Start();
            if(true)
            {
                Elapsed = sw.Elapsed;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }
}

Now it works using Timers instead

using System;
using System.ComponentModel;
using System.Timers;

namespace Eksamen_Januar_2011 { public class ActiveEmployee : INotifyPropertyChanged { public int EmpID { get; set; } public string EmpName { get; set; } private DateTime startDate; private BackgroundWorker worker; private Timer timer;

public ActiveEmployee(int empID, string empName) { startDate = DateTime.Now; worker = new BackgroundWorker(); worker.DoWork += BackgroundWork; timer = new Timer(1000); timer.Elapsed += TimerElapsed; worker.RunWorkerAsync(); } private TimeSpan elapsed; public TimeSpan Elapsed { get { return elapsed; } set { elapsed = value; NotifyPropertyChanged("Elapsed"); } } private void BackgroundWork(object sender, DoWorkEventArgs args) { timer.Start(); } private void TimerElapsed(object sender, ElapsedEventArgs e) { Elapsed = DateTime.Now - startDate; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } }

}

like image 784
Mech0z Avatar asked Jan 13 '11 22:01

Mech0z


2 Answers

You need to implement the INotifyPropertyChanged interface. Modify your class declaration to:

public class Employee : System.ComponentModel.INotifyPropertyChanged

See http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx.

like image 80
JoshL Avatar answered Sep 20 '22 00:09

JoshL


Data-binding and observing change relies on change-notification events; either *Changed (for property *) or INotifyPropertyChanged typically (although custom implementations are possible).

Stopwatch does not provide such; you may be better off using a Timer instead, to update the UI every so often. Just store the DateTime when you start, and whenever the timer fires calculate the offset from then to now.

like image 40
Marc Gravell Avatar answered Sep 21 '22 00:09

Marc Gravell