0

I have a simple class that represents a timer (simplified for clarity):

public class Timer {
    DateTime startTime;

    // How do I notify the UI that this property is changing?
    public TimeSpan Value {
        get {
            return DateTime.Now - startTime;
        }
    }
    public void Start() {
        startTime = DateTime.Now;
    }
}

And a page containing a TextBlock and an instance of a Timer.

I'd like to databind the TextBlock's Text property to show the Timer.Value. However, this field is obviously changing constantly, so firing PropertyChanged events doesn't seem to make any sense.

Is there some way to indicate that a property is always changing, so that the UI updates as fast as is reasonably possible?

Eric
  • 95,302
  • 53
  • 242
  • 374
  • possible duplicate of [Current Date in Silverlight XAML TextBlock](http://stackoverflow.com/questions/2430664/current-date-in-silverlight-xaml-textblock) – Eric Nov 24 '12 at 22:38

3 Answers3

1

That's what PropertyChanged is designed to do. The UI should be able to cope with a constantly changing value.

However, to ensure that you don't flood the UI you should use a timer that gives you control over the interval of each tick:

System.Threading.Timer myTimer;

TimerCallback callback = TimerTick;
myTimer = new System.Threading.Timer(callback, null, 0, 1000);

This starts a timer straight away (the 0) which fires every second (the 1000). Your TimerCallback will look something like this:

void TimerTick(object stateInfo)
{
    // Raise property changed event with DateTime.Now
}
ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • So essentially, I need to fire off property changed event periodically myself, using a `System.Threading.Timer` or `DispatcherTimer` - there's no way to mark a property as "unstable" and have it handled automagically? – Eric Nov 24 '12 at 22:36
1

This is what I came up with:

public class ObservableTimer : Timer, INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;
    // some extension methods are being used here
    public PropertyChangedEventArgs pcValue = Property.Changed<ObservableTimer>(t => t.Value);

    DispatcherTimer dTimer;

    public ObservableTimer() {
        dTimer = new DispatcherTimer();
        dTimer.Interval = TimeSpan.FromMilliseconds(50);
        dTimer.Tick += onTimerTick;
        dTimer.Start();
    }

    private void onTimerTick(object sender, EventArgs e) {
        // some extension methods are being used here
        PropertyChanged.Raise(this, pcValue);
    }
}

As described in ChrisF's answer, this uses a timer to periodically fire the PropertyChanged event.

Community
  • 1
  • 1
Eric
  • 95,302
  • 53
  • 242
  • 374
0

Here's what you can do, you have this class right,

public class Timer {
DateTime startTime;

// How do I notify the UI that this property is changing?
public TimeSpan Value {
    get {
        return DateTime.Now - startTime;
    }
}
public void Start() {
    startTime = DateTime.Now;
}

}

First Apply the INotifyPropertyChanged to the property Value.

Now in XAML you might be having a grid. You need to bind the "Datacontext" of the grid to the current instance of your Timer class. for that there are lots of way, the most simple among them is to name the grid say(as RootGrid). Now in the loaded event of the user control:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
       RootGrid.DataContext = this;
    }

Ok Game over, last step is to bind the TextBlock's Text property to your "Value".

<TextBlock Text="{Binding Value}"/>

and above code in XAML, will do it for you.

Neelesh
  • 116
  • 2
  • 8
  • This doesn't help - my question is really _"how can I apply INotifyPropertyChanged to the `Value` property"_ – Eric Nov 25 '12 at 13:20