开发者

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;

            w开发者_StackOverflow中文版orker.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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜