6

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)); } } }

}

3 Answers 3

6

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.

0
3

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.

1
  • But I did make the PropertyChanged in the bottem of the file? And so whenvever Elapsed = sw.Elapsed; is called (which is all the time) then it should update the control?
    – Mech0z
    Commented Jan 13, 2011 at 22:27
0

What's the point of having the if(true) statement? Did you mean to write while(true)?

You're only updating the elapsed time once in the thread, then it exists.. which is what you're seeing on the form

Not the answer you're looking for? Browse other questions tagged or ask your own question.