diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MetroWpf/FxRates.UI/Controls/TimerTextBlock.cs	Tue Mar 20 20:18:35 2012 +0000
@@ -0,0 +1,187 @@
+using System;
+using System.Threading;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+
+namespace FxRates.UI.Controls
+{
+    public delegate void Invoker();
+
+    public class TimerTextBlock : TextBlock
+    {
+        //private static Timer _UpdateTimer = new Timer(UpdateTimer, null, 1000, 1000);
+
+        public static readonly DependencyProperty TimeSpanProperty =
+            DependencyProperty.Register("TimeSpan", typeof (TimeSpan), typeof (TimerTextBlock),
+                                        new UIPropertyMetadata(TimeSpan.Zero));
+
+        public static readonly DependencyProperty IsStartedProperty =
+            DependencyProperty.Register("IsStarted", typeof (bool), typeof (TimerTextBlock),
+                                        new UIPropertyMetadata(false));
+
+        public static readonly DependencyProperty TimeFormatProperty =
+            DependencyProperty.Register("TimeFormat", typeof (string), typeof (TimerTextBlock),
+                                        new UIPropertyMetadata(null));
+
+        public static readonly DependencyProperty IsCountDownProperty =
+            DependencyProperty.Register("IsCountDown", typeof (bool), typeof (TimerTextBlock),
+                                        new UIPropertyMetadata(false));
+
+        private Invoker _UpdateTimeInvoker;
+
+        public TimerTextBlock()
+        {
+            Init();
+        }
+
+        public TimerTextBlock(Inline inline) : base(inline)
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Represents the time remaining for the count down to complete if
+        /// the control is initialized as a count down timer otherwise, it 
+        /// represents the time elapsed since the timer has started.
+        /// </summary>
+        /// <exception cref="System.ArgumentException">
+        /// </exception>
+        public TimeSpan TimeSpan
+        {
+            get { return (TimeSpan) GetValue(TimeSpanProperty); }
+            set
+            {
+                if (value < TimeSpan.Zero)
+                    throw new ArgumentException();
+
+                SetValue(TimeSpanProperty, value);
+            }
+        }
+
+        // Using a DependencyProperty as the backing store for TimeSpan.  This enables animation, styling, binding, etc...
+
+        public bool IsStarted
+        {
+            get { return (bool) GetValue(IsStartedProperty); }
+            set { SetValue(IsStartedProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for IsStarted. This enables animation, styling, binding, etc...
+
+        /// <summary>
+        /// Format string for displaying the time span value.
+        /// </summary>
+        public string TimeFormat
+        {
+            get { return (string) GetValue(TimeFormatProperty); }
+            set { SetValue(TimeFormatProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for TimeFormat. This enables animation, styling, binding, etc...
+
+        /// <summary>
+        /// Represents whether the control is a CountDown or regular timer.
+        /// </summary>
+        public bool IsCountDown
+        {
+            get { return (bool) GetValue(IsCountDownProperty); }
+            set { SetValue(IsCountDownProperty, value); }
+        }
+
+        public event EventHandler OnCountDownComplete;
+
+        private static event EventHandler OnTick;
+
+        private void Init()
+        {
+            Loaded += TimerTextBlock_Loaded;
+            Unloaded += TimerTextBlock_Unloaded;
+        }
+
+        ~TimerTextBlock()
+        {
+            Dispose();
+        }
+
+        public void Dispose()
+        {
+            OnTick -= TimerTextBlock_OnTick;
+        }
+
+        // Using a DependencyProperty as the backing store for IsCountDown.  This enables animation, styling, binding, etc...
+
+        /// <summary>
+        /// Sets the time span to zero and stops the timer.
+        /// </summary>
+        public void Reset()
+        {
+            IsStarted = false;
+            TimeSpan = TimeSpan.Zero;
+        }
+
+        private static void UpdateTimer(object state)
+        {
+            EventHandler onTick = OnTick;
+            if (onTick != null)
+                onTick(null, EventArgs.Empty);
+        }
+
+        private void TimerTextBlock_Loaded(object sender, RoutedEventArgs e)
+        {
+            var binding = new Binding("TimeSpan");
+            binding.Source = this;
+            binding.Mode = BindingMode.OneWay;
+            binding.StringFormat = TimeFormat;
+
+            SetBinding(TextProperty, binding);
+
+            _UpdateTimeInvoker = UpdateTime;
+
+            OnTick += TimerTextBlock_OnTick;
+        }
+
+        private void TimerTextBlock_Unloaded(object sender, RoutedEventArgs e)
+        {
+            OnTick -= TimerTextBlock_OnTick;
+        }
+
+        private void TimerTextBlock_OnTick(object sender, EventArgs e)
+        {
+            Dispatcher.Invoke(_UpdateTimeInvoker);
+        }
+
+        private void UpdateTime()
+        {
+            if (IsStarted)
+            {
+                TimeSpan step = TimeSpan.FromSeconds(1);
+                if (IsCountDown)
+                {
+                    if (TimeSpan >= TimeSpan.FromSeconds(1))
+                    {
+                        TimeSpan -= step;
+                        if (TimeSpan.TotalSeconds <= 0)
+                        {
+                            TimeSpan = TimeSpan.Zero;
+                            IsStarted = false;
+                            NotifyCountDownComplete();
+                        }
+                    }
+                }
+                else
+                {
+                    TimeSpan += step;
+                }
+            }
+        }
+
+        private void NotifyCountDownComplete()
+        {
+            EventHandler handler = OnCountDownComplete;
+            if (handler != null)
+                handler(this, EventArgs.Empty);
+        }
+    }
+}
\ No newline at end of file