Some time ago i wrote a small widget-like application which was supposed to keep track of tasks, each task had a deadline specified as a DateTime, now if you wa
A timer is the only way I can think of. Since this is an interesting question, I'll put my .02 in. I would encapsulate it doing something like this:
public class CountdownViewModel : INotifyPropertyChanged
{
Func calc;
DispatcherTimer timer;
public CountdownViewModel(DateTime deadline)
: this(() => deadline - DateTime.Now)
{
}
public CountdownViewModel(Func calculator)
{
calc = calculator;
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
var temp = PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs("CurrentValue"));
}
}
public TimeSpan CurrentValue
{
get
{
var result = calc();
if (result < TimeSpan.Zero)
{
return TimeSpan.Zero;
}
return result;
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class MyViewModel
{
public CountdownViewModel DeadlineCountdown { get; private set; }
public DateTime Deadline { get; set; }
public MyViewModel()
{
Deadline = DateTime.Now.AddSeconds(200);
DeadlineCountdown = new CountdownViewModel(Deadline);
}
}
Then you could bind to DeadlineCountdown.CurrentValue directly, or create a CountdownView. You could move the timer to the CountdownView, if you wanted. You could use a static timer so they all update at the same time.
Edit
If Deadline is going to change, you would have to construct the countdown like this:
DeadlineCountdown = new CountdownViewModel(() => this.Deadline - DateTime.Now);