When implementing a date picker that is used to fetch some ‘details’ based on the selected date, the chances are that you don’t want to begin fetching the ‘details’ immediately.
If you did, and made a rapid change to the SelectedDate (maybe holding down an arrow key), the asynchronous fetch will be repeated a large number of times.
To prevent this, implement a deferral on the selected date change, for example:
public class DeferredDP : DatePicker { public DeferredDP() { this.DefaultStyleKey = typeof(DatePicker); base.SelectedDateChanged += new EventHandler(DeferredDP_SelectedDateChanged); } DispatcherTimer _timer; void DeferredDP_SelectedDateChanged(object sender, SelectionChangedEventArgs e) { /// if there is an instance of the timer already running stop it. if (_timer != null) { _timer.Stop(); _timer = null; } /// only trigger the selection changed event when the date has been changed if (e.AddedItems.Count == 1 && e.AddedItems[0] is DateTime) { if (SelectionDelay.HasValue) { /// if the timer delay has been set, delay the setting of the value _timer = new DispatcherTimer(); _timer.Interval = new TimeSpan(0,0,0,0,SelectionDelay.Value); _timer.Tick += (s1, e1) => { SetValue(SelectedDateDeferredProperty, (DateTime)e.AddedItems[0]); if (_timer != null) { _timer.Stop(); _timer = null; } }; _timer.Start(); } else { // if the timer delay is not set, set the property immediately. SetValue(SelectedDateDeferredProperty, (DateTime)e.AddedItems[0]); } } } /// /// Milliseconds delay before the selected date value is updated. /// public int? SelectionDelay { get { return (int?)GetValue(SelectionDelayProperty); } set { SetValue(SelectionDelayProperty, value); } } public static readonly DependencyProperty SelectionDelayProperty = DependencyProperty.Register("SelectionDelay", typeof(int?), typeof(DeferredDP), new PropertyMetadata(null)); public DateTime? SelectedDateDeferred { get { return (DateTime?)GetValue(SelectedDateDeferredProperty); } set { SetValue(SelectedDateDeferredProperty, value); } } public static readonly DependencyProperty SelectedDateDeferredProperty = DependencyProperty.Register("SelectedDateDeferred", typeof(DateTime?), typeof(DeferredDP), new PropertyMetadata(null, SelectedDateDeferredChanged)); public static void SelectedDateDeferredChanged(DependencyObject d, DependencyPropertyChangedEventArgs args) { DeferredDP instance = d as DeferredDP; if (instance.SelectedDateDeferred != instance.SelectedDateDeferred) { instance.SelectedDateDeferred = instance.SelectedDateDeferred; } } }
Leave a Reply