I currently use a valueconverters in XAML to display my viewmodel DateTime fields in "x minutes ago" format. I need to have them updated periodically without causing too much overhead. At any one time I have a dozen on screen, and a few dozen off screen. What is the best strategy?
In the constructor of the viewmodel object, have them register themselves to a static 'ViewRefresher' that periodically goes through all the objects and fires PropertyChanged handlers, on the registered fields.
Refresh the content/items control objects that are holding my objects
Something else?
I will go ahead and try both approaches above while I wait for answers and report back in case it helps someone else.
Update: OK, thanks to csteinmueller for putting me on the events path. Much cleaner than registering/deregistering objects. I believe the following strategy should not be leaky.
public class DateTimeC: INotifyPropertyChanged
{
public DateTime DT {get; set;}
public event PropertyChangedEventHandler PropertyChanged;
public DateTimeC(DateTime dt)
{
DT = dt;
ViewRefresher.FiveSecondsTick += () =>
{ PropertyChanged(this, new PropertyChangedEventArgs("DT")); };
}
}
public delegate void TickHandler();
public static class ViewRefresher
{
private static DispatcherTimer dt = new DispatcherTimer();
private static int counter = 0;
public static event TickHandler FiveSecondsTick;
public static event TickHandler OneMinuteTick;
static ViewRefresher()
{
dt.Interval = TimeSpan.FromSeconds(5);
dt.Tick += Tick;
dt.Start();
}
private static void Tick(object sender, EventArgs e)
{
if (FiveSecondsTick != null)
FiveSecondsTick();
if (counter++ != 12) return;
counter = 0;
if (OneMinuteTick != null)
OneMinuteTick();
}
}
Would have been nice if I could derive from DateTime directly instead of inlining as a field, but it's sealed.
UPDATE 2: This does seem to have a memory leak after all. You need to unhook event for DateTimeC to be garbage-collected, or use a weak reference.