C#
WPF 시계만들기 (Rotation 사용)
hyun0229
2022. 6. 16. 01:41
<Window x:Class="_045_RotationClock.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:_045_RotationClock"
mc:Ignorable="d"
Title="Rotation_Clock" Height="400" Width="400">
<Grid>
<Canvas x:Name="aClock" Width="300" Height="300">
<Rectangle Width="300" Height="300" Stroke="LightSteelBlue"/>
<Ellipse Width="300" Height="300" Stroke="LightSteelBlue" StrokeThickness="2" RenderTransformOrigin="0.5,0.5"/>
<Line X1="0" Y1="150" X2="300" Y2="150" Stroke="LightBlue"/>
<Line X1="150" Y1="0" X2="150" Y2="300" Stroke="LightBlue"/>
<Line Name="secHand" Stroke="Red" StrokeThickness="2" StrokeEndLineCap="Round"/>
<Line Name="minHand" Stroke="Green" StrokeThickness="4" StrokeEndLineCap="Round"/>
<Line Name="hourHand" Stroke="Blue" StrokeThickness="6" StrokeEndLineCap="Round"/>
<Ellipse Name="center" Width="20" Height="20" Margin="140" Stroke="DarkOliveGreen" StrokeThickness="2" Fill="Chocolate" RenderTransformOrigin="1.17,0.66"/>
</Canvas>
</Grid>
</Window>
디자인 Grid를 사용하였고 전과 마찬가지로 시계를 그리기위해 Canvas를 사용하였다.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//시계판 그리기
DrawFace();
MakeClockHands();
DispatcherTimer dt=new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 0, 0, 10); //0.01초
dt.Tick += Dt_Tick;
dt.Start();
}
전과 마찬가지로 DispatcherTimer를 사용하여 시간을 계산하였다.
Dt_Tick()
private void Dt_Tick(object sender, EventArgs e)
{
DateTime c=DateTime.Now;
double hDeg=c.Hour*30+c.Minute*0.5;
double mDeg = c.Minute * 6;
double sDeg = c.Second * 6;
RotateTransform hRt =new RotateTransform(hDeg);
hRt.CenterX = hourHand.X1;
hRt.CenterY = hourHand.Y1;
hourHand.RenderTransform = hRt;
RotateTransform mRt = new RotateTransform(mDeg);
mRt.CenterX = hourHand.X1;
mRt.CenterY = hourHand.Y1;
minHand.RenderTransform = mRt;
RotateTransform sRt = new RotateTransform(sDeg);
sRt.CenterX = hourHand.X1;
sRt.CenterY = hourHand.Y1;
secHand.RenderTransform = sRt;
}
hDeg, mDeg, sDeg는 각각 시 분 초이며 시는 아날로그 시계의 특성에 맞춰 분을 더해주었다.
분에도 초에따라 변하게 하고싶다면 초를 더해주면 된다.
RotateTransform을 각도를 지정하면 회전시켜줍니다.....
RotateTransform의 자세한 설명은 RotateTransform을 참조
private void MakeClockHands()
{
int w = 300;
int h = 300;
secHand.X1=w/2;
secHand.Y1 =h/2;
secHand.X2 =w/2;
secHand.Y2 = 20;
minHand.X1 = w / 2;
minHand.Y1 = h / 2;
minHand.X2 = w / 2;
minHand.Y2 = 40;
hourHand.X1 = w / 2;
hourHand.Y1 = h / 2;
hourHand.X2 = w / 2;
hourHand.Y2 = 60;
}
sec, min, hourHand는 Xmal에서 생성한 Line의 Name입니다.
DrawFace()
private void DrawFace()
{
Line[] marking = new Line[60];
int w=300;
for (int i = 0; i < 60; i++)
{
marking[i] = new Line();
marking[i].Stroke = Brushes.LightSteelBlue;
marking[i].X1 = w / 2;
marking[i].Y1 = 2;
marking[i].X2=w/2;
marking[i].Y2=20;
if (i%5==0)
{
marking[i].StrokeThickness = 5;
marking[i].Y2 = 20;
}
else
{
marking[i].StrokeThickness = 2;
marking[i].Y2 = 10;
}
RotateTransform rt = new RotateTransform(6 * i);
rt.CenterX = 150;
rt.CenterY = 150;
marking[i].RenderTransform = rt;
aClock.Children.Add(marking[i]);
}
}
RotateTransform을 시계의 눈금을 그려줍니다. 5단위로 구분할수 있도록 5로 나누었을때 나머지가 0이 되는 선은 좀더 길고 굵게 그려줍니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace _045_RotationClock
{
/// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//시계판 그리기
DrawFace();
MakeClockHands();
DispatcherTimer dt=new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 0, 0, 10); //0.01초
dt.Tick += Dt_Tick;
dt.Start();
}
private void Dt_Tick(object sender, EventArgs e)
{
DateTime c=DateTime.Now;
double hDeg=c.Hour*30+c.Minute*0.5;
double mDeg = c.Minute * 6;
double sDeg = c.Second * 6;
RotateTransform hRt =new RotateTransform(hDeg);
hRt.CenterX = hourHand.X1;
hRt.CenterY = hourHand.Y1;
hourHand.RenderTransform = hRt;
RotateTransform mRt = new RotateTransform(mDeg);
mRt.CenterX = hourHand.X1;
mRt.CenterY = hourHand.Y1;
minHand.RenderTransform = mRt;
RotateTransform sRt = new RotateTransform(sDeg);
sRt.CenterX = hourHand.X1;
sRt.CenterY = hourHand.Y1;
secHand.RenderTransform = sRt;
}
private void MakeClockHands()
{
int w = 300;
int h = 300;
secHand.X1=w/2;
secHand.Y1 =h/2;
secHand.X2 =w/2;
secHand.Y2 = 20;
minHand.X1 = w / 2;
minHand.Y1 = h / 2;
minHand.X2 = w / 2;
minHand.Y2 = 40;
hourHand.X1 = w / 2;
hourHand.Y1 = h / 2;
hourHand.X2 = w / 2;
hourHand.Y2 = 60;
}
private void DrawFace()
{
Line[] marking = new Line[60];
int w=300;
for (int i = 0; i < 60; i++)
{
marking[i] = new Line();
marking[i].Stroke = Brushes.LightSteelBlue;
marking[i].X1 = w / 2;
marking[i].Y1 = 2;
marking[i].X2=w/2;
marking[i].Y2=20;
if (i%5==0)
{
marking[i].StrokeThickness = 5;
marking[i].Y2 = 20;
}
else
{
marking[i].StrokeThickness = 2;
marking[i].Y2 = 10;
}
RotateTransform rt = new RotateTransform(6 * i);
rt.CenterX = 150;
rt.CenterY = 150;
marking[i].RenderTransform = rt;
aClock.Children.Add(marking[i]);
}
}
}
}
전체코드