简体   繁体   中英

Databinding issue with stopwatched elapsed

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

}

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 .

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM