XAML+C#で簡単なタイマーを作る

初投稿です。

公開ダウンローダでは、画面表示の30秒後にダウンロードリンクが有効になるサイトがよくあります。

30秒を待ち切れずに他の事を始めてしまうと、うっかり見逃してしまってセッションが切れて最初から
やり直し・・・というのを何度も繰り返し、勉強がてら指定秒数後に通知をするタイマーを作ることにしました。

今回の記事では、以下の機能を持つアプリケーションを作成します。
・指定秒数の経過後、通知を表示する
・経過時間をms単位で画面に表示する
・タイマーを一時停止する
・一時停止したタイマーをリセット(初期化)する

```xml:MainWindow.xaml
<Window x:Class="SimpleTimer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="StopWatch"  Height="195" Width="369" ResizeMode="CanMinimize">
    <Grid>
        <Label x:Name="lblTime" Content="00:00:000" HorizontalAlignment="Left" Height="54" Margin="37,33,0,0" VerticalAlignment="Top" Width="276" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="36"/>
        <Button x:Name="btnStart" Content="Start" HorizontalAlignment="Left" Margin="37,111,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <Button x:Name="btnStop" Content="Stop" HorizontalAlignment="Left" Margin="137,111,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <Button x:Name="btnReset" Content="Reset" HorizontalAlignment="Left" Margin="238,111,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
    </Grid>
</Window>
```



```csharp:MainWindow.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Threading;

namespace SimpleTimer
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        DispatcherTimer dispatcherTimer;    // タイマーオブジェクト
        int TimeLimit = 30;                 // 制限時間
        DateTime StartTime;                 // カウント開始時刻
        TimeSpan nowtimespan;               // Startボタンが押されてから現在までの経過時間
        TimeSpan oldtimespan;               // 一時停止ボタンが押されるまでに経過した時間の蓄積

        public MainWindow()
        {
            InitializeComponent();

            // コンポーネントの状態を初期化　
            lblTime.Content = "00:00:000";
            btnStart.IsEnabled = true;
            btnStop.IsEnabled = false;
            btnReset.IsEnabled = true;

            // タイマーのインスタンスを生成
            dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal);
            dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1);
            dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);

            // タイマー開始
            TimerStart();

        }

        // タイマー Tick処理
        void dispatcherTimer_Tick(object sender, EventArgs e)
        {
            nowtimespan = DateTime.Now.Subtract(StartTime);
            lblTime.Content = oldtimespan.Add(nowtimespan).ToString(@"mm\:ss\:fff");

            if (TimeSpan.Compare(oldtimespan.Add(nowtimespan), new TimeSpan(0, 0, TimeLimit)) >= 0)
            {
                TimerStop();
                TimerReset();
                MessageBox.Show(String.Format("{0}秒経過しました。", TimeLimit),
                                "Infomation",MessageBoxButton.OK,MessageBoxImage.Information);
            }
        }

        // ボタンクリック時の処理分岐
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Control ctrl = (Control)sender;
            switch (ctrl.Name)
            {
                case "btnStart":
                    TimerStart();
                    break;

                case "btnStop":
                    TimerStop();
                    break;

                case "btnReset":
                    TimerReset();
                    break;

                default:
                    break;
            }
        }

        // タイマー操作：開始
        private void TimerStart()
        {
            btnStart.IsEnabled = false;
            btnStop.IsEnabled = true;
            btnReset.IsEnabled = false;
            StartTime = DateTime.Now;
            dispatcherTimer.Start();
        }

        // タイマー操作：停止
        private void TimerStop()
        {
            btnStart.IsEnabled = true;
            btnStop.IsEnabled = false;
            btnReset.IsEnabled = true;
            oldtimespan = oldtimespan.Add(nowtimespan);
            dispatcherTimer.Stop();
        }

        // タイマー操作：リセット
        private void TimerReset()
        {
            oldtimespan = new TimeSpan();
            lblTime.Content = "00:00:000";
        }

    }
}

```

一通りは動作しますが、通知が標準のメッセージボックスの表示ですので、これでは見逃してしまいます。

次回は *WPF NotifyIcon* ( http://www.hardcodet.net/wpf-notifyicon )を組み込み、
XAMLでデザインしたポップアップアイコンを通知領域に表示してみようと思います。
うとうとしていても気づくように、サウンドも鳴らしてみます。
https://github.com/MakotoUwaya/SimpleTimer