WPF における タイマー処理

2021年4月19日

この記事では WPF を用いた際、 タイマー処理 の実装がわからなかったので調査がてらメモしたことを書きたいと思います。

Windows Formsにお別れを

いままでC#でデスクトップアプリケーション開発といえばWindows Formsと呼ばれるプラットフォームを使ってきました。
デザイナにポイポイポイっと部品を配置してClickイベント付加してロジック組んで完成!ととても簡単にアプリケーションを作成できました。

しかし時代の流れは残酷なものです。WPFというプラットフォームが登場。WPFのほうがアプリケーションの表現力が高くなにより処理が高速です。(※個人の感想です)
世界的にもWPF推しの流れになってきているようなのでそろそろWindows Formsとお別れしたいと思います。
WPFはxamlというXMLフォーマットの形式でGUIを定義していきます。

もちろんデザイナで部品をドラッグアンドドロップして配置することもできますが私の場合は結局xamlで実装するほうが早いという結論に至りました。
なかなか覚えるのは大変ですが(特にデザイナでの部品の位置調整が大変!)がんばっています。

いままでの使っていたタイマー処理

さて、Windows Formsにお別れをしたのでこのパッケージ配下の部品は使えないわけです。(そんなことはないのかもしれませんが)
WPFで開発していて「こういうときWPFではどうするのだろう?」という問題が山のように出てきます。

そんな問題の中の一つがタイマー処理でした。
Windows Formsを使用しているときは System.Windows.Forms.Timerを使用していました。

調べてみるとタイマー処理はいくつか選択肢があるようです。(以下引用させていただきました。ありがとうございます。)

種類 アセンブリ 用途
System.Timers.Timer System 普通の定周期処理
System.Threading.Timer mscorlib 普通の定周期処理
System.Windows.Forms.Timer System.Windows.Forms WinForm GUI専用
System.Windows.Threading.DispatcherTimer WindowsBase WPF GUI専用

この中で「WPF GUI専用」であるというDispatcherTimer にビビビっと来たのでこちらを使用します。
しかしこちらの記事の方はお詳しいですね。尊敬します!

 

DispatcherTimer

私が惹かれたのはここです。

Timerに設定したイベントハンドラ内でGUIコントロールを操作した場合は例外(InvaliedOperationException)が発生しません。

え!?簡単でいいじゃん!。私はお手軽な方に流されてしまう性格なのです😗
GUIでのスレッド処理ってちょっと億劫なんですよね。GUIコントロールのスレッド以外でGUIコントロールを操作すると例外になってしまうんですよ。
これはまが別の機会にご紹介します。
そんな処理がデフォルトで必要ないなんて素敵です。
制度が低い・・・とな🤔。まあ気にしない方向で行きます。

実際使ってみた

プロジェクトを作成します。

デザイナ等を使用し、画面を作ります。

コーディングを行います。


using System;
using System.Windows;
using System.Windows.Threading;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        //  タイマーイベント
        DispatcherTimer myTimer = new DispatcherTimer();

        public MainWindow()
        {
            InitializeComponent();

            
            myTimer.Tick += new EventHandler(myTimer_Tick);
            myTimer.Interval = new TimeSpan(0, 0, 3); //3秒間隔に設定
            
        }
        /// <summary>
        /// 一定間隔で実行される処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void myTimer_Tick(object sender, EventArgs e)
        {
            // チェックボックスのオンオフ
            this.Hoge_CheckBox.IsChecked = !this.Hoge_CheckBox.IsChecked;
        }

        /// <summary>
        /// スタートボタンクリック
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Start_Btn_Click(object sender, RoutedEventArgs e)
        {
            myTimer.Start();
        }
    }
}

それでは動かしてみましょう!

とっても簡単でいいですよね!
これを応用すればGUIの裏側でいろんな定期処理ができそうです。
WPFでの開発にはなかなか慣れませんがこれからも精進します☺