はじめに
WPFのDispatcherTimerクラスを使い、簡単なアナログ時計のサンプルコードです。
概要は以下のとおり。
- 秒針、分針、時針の3つをLineオブジェクトとして表す。
- 3つのLineオブジェクトの、RenderTransformプロパティには、RotateTransformを設定する。
- DispatcherTimerで、1秒おきに、上記RotateTransformの回転角度を変化させる。
実行例
以下に、作成したアプリのスクリーンショットを示します。秒針は1秒おきに動いていきます。
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();
}
}
}