comparison MetroWpf/FxRates.UI/Controls/TimerTextBlock.cs @ 24:a8b50a087544

Stocks and FxRates working, new menu introduced. Working nicely so far
author adminsh@apollo
date Tue, 20 Mar 2012 20:18:35 +0000
parents
children
comparison
equal deleted inserted replaced
23:399398841fd0 24:a8b50a087544
1 using System;
2 using System.Threading;
3 using System.Windows;
4 using System.Windows.Controls;
5 using System.Windows.Data;
6 using System.Windows.Documents;
7
8 namespace FxRates.UI.Controls
9 {
10 public delegate void Invoker();
11
12 public class TimerTextBlock : TextBlock
13 {
14 //private static Timer _UpdateTimer = new Timer(UpdateTimer, null, 1000, 1000);
15
16 public static readonly DependencyProperty TimeSpanProperty =
17 DependencyProperty.Register("TimeSpan", typeof (TimeSpan), typeof (TimerTextBlock),
18 new UIPropertyMetadata(TimeSpan.Zero));
19
20 public static readonly DependencyProperty IsStartedProperty =
21 DependencyProperty.Register("IsStarted", typeof (bool), typeof (TimerTextBlock),
22 new UIPropertyMetadata(false));
23
24 public static readonly DependencyProperty TimeFormatProperty =
25 DependencyProperty.Register("TimeFormat", typeof (string), typeof (TimerTextBlock),
26 new UIPropertyMetadata(null));
27
28 public static readonly DependencyProperty IsCountDownProperty =
29 DependencyProperty.Register("IsCountDown", typeof (bool), typeof (TimerTextBlock),
30 new UIPropertyMetadata(false));
31
32 private Invoker _UpdateTimeInvoker;
33
34 public TimerTextBlock()
35 {
36 Init();
37 }
38
39 public TimerTextBlock(Inline inline) : base(inline)
40 {
41 Init();
42 }
43
44 /// <summary>
45 /// Represents the time remaining for the count down to complete if
46 /// the control is initialized as a count down timer otherwise, it
47 /// represents the time elapsed since the timer has started.
48 /// </summary>
49 /// <exception cref="System.ArgumentException">
50 /// </exception>
51 public TimeSpan TimeSpan
52 {
53 get { return (TimeSpan) GetValue(TimeSpanProperty); }
54 set
55 {
56 if (value < TimeSpan.Zero)
57 throw new ArgumentException();
58
59 SetValue(TimeSpanProperty, value);
60 }
61 }
62
63 // Using a DependencyProperty as the backing store for TimeSpan. This enables animation, styling, binding, etc...
64
65 public bool IsStarted
66 {
67 get { return (bool) GetValue(IsStartedProperty); }
68 set { SetValue(IsStartedProperty, value); }
69 }
70
71 // Using a DependencyProperty as the backing store for IsStarted. This enables animation, styling, binding, etc...
72
73 /// <summary>
74 /// Format string for displaying the time span value.
75 /// </summary>
76 public string TimeFormat
77 {
78 get { return (string) GetValue(TimeFormatProperty); }
79 set { SetValue(TimeFormatProperty, value); }
80 }
81
82 // Using a DependencyProperty as the backing store for TimeFormat. This enables animation, styling, binding, etc...
83
84 /// <summary>
85 /// Represents whether the control is a CountDown or regular timer.
86 /// </summary>
87 public bool IsCountDown
88 {
89 get { return (bool) GetValue(IsCountDownProperty); }
90 set { SetValue(IsCountDownProperty, value); }
91 }
92
93 public event EventHandler OnCountDownComplete;
94
95 private static event EventHandler OnTick;
96
97 private void Init()
98 {
99 Loaded += TimerTextBlock_Loaded;
100 Unloaded += TimerTextBlock_Unloaded;
101 }
102
103 ~TimerTextBlock()
104 {
105 Dispose();
106 }
107
108 public void Dispose()
109 {
110 OnTick -= TimerTextBlock_OnTick;
111 }
112
113 // Using a DependencyProperty as the backing store for IsCountDown. This enables animation, styling, binding, etc...
114
115 /// <summary>
116 /// Sets the time span to zero and stops the timer.
117 /// </summary>
118 public void Reset()
119 {
120 IsStarted = false;
121 TimeSpan = TimeSpan.Zero;
122 }
123
124 private static void UpdateTimer(object state)
125 {
126 EventHandler onTick = OnTick;
127 if (onTick != null)
128 onTick(null, EventArgs.Empty);
129 }
130
131 private void TimerTextBlock_Loaded(object sender, RoutedEventArgs e)
132 {
133 var binding = new Binding("TimeSpan");
134 binding.Source = this;
135 binding.Mode = BindingMode.OneWay;
136 binding.StringFormat = TimeFormat;
137
138 SetBinding(TextProperty, binding);
139
140 _UpdateTimeInvoker = UpdateTime;
141
142 OnTick += TimerTextBlock_OnTick;
143 }
144
145 private void TimerTextBlock_Unloaded(object sender, RoutedEventArgs e)
146 {
147 OnTick -= TimerTextBlock_OnTick;
148 }
149
150 private void TimerTextBlock_OnTick(object sender, EventArgs e)
151 {
152 Dispatcher.Invoke(_UpdateTimeInvoker);
153 }
154
155 private void UpdateTime()
156 {
157 if (IsStarted)
158 {
159 TimeSpan step = TimeSpan.FromSeconds(1);
160 if (IsCountDown)
161 {
162 if (TimeSpan >= TimeSpan.FromSeconds(1))
163 {
164 TimeSpan -= step;
165 if (TimeSpan.TotalSeconds <= 0)
166 {
167 TimeSpan = TimeSpan.Zero;
168 IsStarted = false;
169 NotifyCountDownComplete();
170 }
171 }
172 }
173 else
174 {
175 TimeSpan += step;
176 }
177 }
178 }
179
180 private void NotifyCountDownComplete()
181 {
182 EventHandler handler = OnCountDownComplete;
183 if (handler != null)
184 handler(this, EventArgs.Empty);
185 }
186 }
187 }