1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Threading;
namespace NuGet.WebMatrix
{
/// <summary>
/// A timer class that delays property-change notifications until the application is idle
/// </summary>
public sealed class IdleDelayTimer : FrameworkElement
{
public static readonly DependencyProperty OutputProperty = DependencyProperty.Register(
"Output",
typeof(object),
typeof(IdleDelayTimer));
public static readonly DependencyProperty InputProperty = DependencyProperty.Register(
"Input",
typeof(object),
typeof(IdleDelayTimer),
new PropertyMetadata(Input_PropertyChanged));
public IdleDelayTimer(Binding source)
{
this.Source = source;
this.SetBinding(InputProperty, this.Source);
this.Delay = TimeSpan.FromMilliseconds(500);
}
public object Output
{
get
{
return this.GetValue(OutputProperty);
}
set
{
this.SetValue(OutputProperty, value);
}
}
public object Input
{
get
{
return (string)this.GetValue(InputProperty);
}
set
{
this.SetValue(InputProperty, value);
}
}
private BindingBase Source
{
get;
set;
}
/// <summary>
/// The delay between the input and output, defaults to 500 ms
/// </summary>
public TimeSpan Delay
{
get;
set;
}
private DateTime? QueueTime
{
get;
set;
}
private DispatcherTimer Timer
{
get;
set;
}
private void OnInputChanged()
{
this.QueueTime = DateTime.UtcNow;
}
private void Timer_Tick(object sender, EventArgs e)
{
if (this.QueueTime != null)
{
if (DateTime.UtcNow > (this.QueueTime + this.Delay))
{
// propegate the value
this.QueueTime = null;
this.Output = this.Input;
}
}
}
private static void Input_PropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var adapter = sender as IdleDelayTimer;
if (adapter != null)
{
adapter.OnInputChanged();
}
}
public void Start()
{
if (this.Timer == null)
{
this.Timer = new DispatcherTimer(DispatcherPriority.ApplicationIdle);
this.Timer.Interval = new TimeSpan(0, 0, 0, 0, 50);
this.Timer.Tick += new EventHandler(Timer_Tick);
this.Timer.Start();
}
}
public void Stop()
{
if (this.Timer != null)
{
this.Timer.Stop();
this.Timer.Tick -= Timer_Tick;
this.Timer = null;
}
}
}
}
|