Help us understand the problem. What is going on with this article?

WPFのDispatcherTimerクラスを使い簡易アナログ時計を作成する

はじめに

WPFのDispatcherTimerクラスを使い、簡単なアナログ時計のサンプルコードです。

概要は以下のとおり。

  • 秒針、分針、時針の3つをLineオブジェクトとして表す。
  • 3つのLineオブジェクトの、RenderTransformプロパティには、RotateTransformを設定する。
  • DispatcherTimerで、1秒おきに、上記RotateTransformの回転角度を変化させる。

実行例

以下に、作成したアプリのスクリーンショットを示します。秒針は1秒おきに動いていきます。

2019-06-01 14_18_29.png

XAMLを定義する

XAMLを示します。
Canvasの中に、3つのLine(時針、分針、秒針)を定義しています。

RotateTransformのAngleプロパティを変化させることで、それぞれの針を動かします。

<Window x:Class="WpfAnalogClock1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfAnalogClock1"
        mc:Ignorable="d"
        Title="Clock" Height="230" Width="220" Loaded="Window_Loaded" >
    <Canvas Width="200" Height="200">
        <Line x:Name="HourLine"  Stroke="Black" Fill="Black" 
              X1="100" Y1="100" X2="100" Y2="35"              
               StrokeThickness="3" >
            <Line.RenderTransform>
                <RotateTransform  x:Name="AngleHour" Angle="0" 
                                  CenterX="100" CenterY="100"/>
            </Line.RenderTransform>
        </Line>
        <Line x:Name="MinuteLine"  Stroke="Black" Fill="Black" 
              X1="100" Y1="100" X2="100" Y2="15"              
               StrokeThickness="2" >
            <Line.RenderTransform>
                <RotateTransform x:Name="AngleMinute"  Angle="0" 
                                 CenterX="100" CenterY="100"/>
            </Line.RenderTransform>
        </Line>
        <Line x:Name="SecondLine"  Stroke="Black" Fill="LightGray"
              X1="100" Y1="120" X2="100" Y2="10"  >
            <Line.RenderTransform>
                <RotateTransform x:Name="AngleSecond" Angle="0"  
                                 CenterX="100" CenterY="100"/>
            </Line.RenderTransform>
        </Line>
        <Ellipse Fill="Black" Width="6" Height="6" HorizontalAlignment="Center"
            VerticalAlignment="Center" 
            Canvas.Top="97" Canvas.Left="97"/>
    </Canvas>
</Window>

絵心のない僕は、時針、分針、秒針の描画にLineオブジェクトを使いましたが、PolygonやPathを使ってもうすこし時計らしい針にし、背景に文字盤を加えれば、見栄えも良くなると思います。

その際、C#のコードでは、RotateTransform の名前に対して、値を設定していますので、C#側は一切手を入れる必要はないはずです。

C#のコード

C#のコードは、オブジェクトの回転角度を変えるだけですので、とても単純なコードになっています。

WindowのLoadedイベントで、DispatcherTimerオブジェクトを生成し、タイマーをスタートさせます。

Tickイベントが1秒おきに発生しますので、 そのイベントハンドラで、Updateメソッドを呼び出しています。 Updateメソッドでは、現在の時刻を取得し、秒針、分針、時針の針の角度を求め、 それぞれの針に対応するLineオブジェクトの回転角度を更新しています。

このコードは、GitHubで公開しています。

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

namespace WpfAnalogClock1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Update();
            DispatcherTimer timer = 
                new DispatcherTimer(DispatcherPriority.Normal, this.Dispatcher);
            timer.Interval = new TimeSpan(0, 0, 1);
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        void Update()
        {
            DateTime dt = DateTime.Now;
            this.AngleSecond.Angle = dt.Second * 360.0 / 60.0;
            this.AngleMinute.Angle = (dt.Minute + dt.Second / 60.0) * 360.0 / 60.0;
            this.AngleHour.Angle = (dt.Hour + dt.Minute / 60.0) * 360.0 / 12;
        }

        void Timer_Tick(object sender, EventArgs e)
        {
            Update();
        }
    }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした