酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windowsストアアプリでタイマーを使って時計アプリを作る

アプリケーションフレームワークには、ほぼ確実にタイマー機能が存在しています。

Metroスタイルアプリにもタイマー機能は、Windows.UI.Xaml名前空間のDispatcherTimerクラスという形で用意されています。このDispatcherTimerクラスを使って時計アプリを作ってみましょう。

Visual Studio 2012を起動し、ツールバーの[ファイル]から順に[新規作成]、[プロジェクト]をクリックします。

[新しいプロジェクト]ダイアログが表示されますので、左のリストから[テンプレート]、[Visual Studio C#]、[Windows Metro style]を選択します。右にいくつかのテンプレートが並んでいるので[Blank App (XAML)]を選択してアプリケーション名を入力して[OK]ボタンをクリックします。アプリケーションの名前は「TimerSample」とします。

MainPage.xaml

<Page
    x:Class="TimerSample.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TimerSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock x:Name="textBlock" HorizontalAlignment="Center"
            VerticalAlignment="Center" FontSize="48"/>
    </Grid>
</Page>

MainPage.xaml.cs

画面突入時のOnNavigatedToメソッド内にてタイマーを起動します。Windows.UI.Xaml名前空間のDispatcherTimerクラスのインスタンスを生成して、IntervalプロパティにTimeSpanを設定します。時計アプリなので1秒ごとにタイマーが満了させるように指定しました。

タイマーが満了するとTickイベントが発生し、以下のサンプルコードの場合イベントハンドラに設定したtimer_Tickメソッドが呼び出されます。

Windows.UI.Xaml.DispatcherTimer timer = null;

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    timer = new Windows.UI.Xaml.DispatcherTimer();
    timer.Interval = TimeSpan.FromSeconds(1);
    timer.Tick += timer_Tick;
    timer.Start();
}

timer_Tickメソッドでは、TextBlockコントロールのTextプロパティに現在時刻を設定しています。

void timer_Tick(object sender, object e)
{
    textBlock.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
}

画面非表示時の対応として、タイマーが動き続けるのは意図しない動作をまねく恐れがあるため、画面脱出時のOnNavigatedFromメソッド内でタイマーを明示的に止めるようにしています。

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    if (timer != null) timer.Stop();
}

かなりシンプルなソースコードになりましたが、MainPage.xaml.csを表示させると以下のようになります。

using System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace TimerSample
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        Windows.UI.Xaml.DispatcherTimer timer = null;

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            timer = new Windows.UI.Xaml.DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += timer_Tick;
            timer.Start();
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            if (timer != null)
            {
                timer.Stop();
            }
        }

        void timer_Tick(object sender, object e)
        {
            textBlock.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
        }
    }
}