C# WPF로 다음과 같은 Analog Clock 을 RotateTransform 을 이용하여 구현한다.
RotateTransform을 이용하면 시침, 분침, 초침을 만들어두고, 1초에 한번씩 현재 시간에 따라 시침, 분침, 초침의 각도를 계산한 후, 시계의 중심좌표를 중심으로 각 바늘의 각도만큼 회전시켜 줌으로써 시계를 만들 수 있다. 삼각함수를 써서 바늘의 좌표를 계산하여 그리는 것보다 간단하다.
눈금도 같은 방법으로 간단히 그릴 수 있다. 소스를 참조하시길...
// XAML
<Window x:Class="Rotation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="330">
<Canvas Name="myCanvas">
</Canvas>
</Window>
// CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 Rotation
{
/// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainWindow : Window
{
private double hourDeg;
private double secDeg;
private double minDeg;
private Line hourHand;
private Line minHand;
private Line secHand;
//private TextBlock tb;
public MainWindow()
{
InitializeComponent();
myCanvas.Width = 300;
myCanvas.Height = 300;
Rectangle r = new Rectangle();
r.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
r.Width = 300;
r.Height = 300;
myCanvas.Children.Add(r);
// Draw Face
DrawFace();
// make Hands
secHand = new Line();
secHand.Stroke = Brushes.Red;
secHand.StrokeThickness = 2;
secHand.X1 = r.Width / 2;
secHand.Y1 = r.Height / 2;
secHand.X2 = r.Width / 2;
secHand.Y2 = 20;
minHand = new Line();
minHand.Stroke = Brushes.Green;
minHand.StrokeThickness = 4;
minHand.X1 = r.Width / 2;
minHand.Y1 = r.Height / 2;
minHand.X2 = r.Width / 2;
minHand.Y2 = 40;
hourHand = new Line();
hourHand.Stroke = Brushes.Blue;
hourHand.StrokeThickness = 6;
hourHand.X1 = r.Width / 2;
hourHand.Y1 = r.Height / 2;
hourHand.X2 = r.Width / 2;
hourHand.Y2 =60;
getCurrentTime();
DispatcherTimer dt = new DispatcherTimer();
dt.Tick += new EventHandler(dt_Tick);
dt.Interval = new TimeSpan(0, 0, 1);
dt.Start();
}
private void DrawFace()
{
//double radius = myCanvas.Width / 2;
Ellipse circle = new Ellipse();
circle.Width = 300;
circle.Height = 300;
circle.Stroke = Brushes.LightSteelBlue;
circle.StrokeThickness = 2;
myCanvas.Children.Add(circle);
Line[] marking = new Line[60];
for (int i = 0; i < 60; i++)
{
marking[i] = new Line();
marking[i].Stroke = Brushes.LightSteelBlue;
marking[i].X1 = circle.Width / 2; marking[i].Y1 = 2;
marking[i].X2 = circle.Width / 2;
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;
myCanvas.Children.Add(marking[i]);
}
Line l1 = new Line();
l1.X1 = 0; l1.Y1 = 150; l1.X2 = 300; l1.Y2 = 150;
l1.Stroke = Brushes.LightBlue;
myCanvas.Children.Add(l1);
Line l2 = new Line();
l2.X1 = 150; l2.Y1 = 0; l2.X2 = 150; l2.Y2 = 300;
l2.Stroke = Brushes.LightBlue;
myCanvas.Children.Add(l2);
}
private void getCurrentTime()
{
DateTime currentTime = new DateTime();
currentTime = DateTime.Now;
int hour = currentTime.Hour;
int min = currentTime.Minute;
int sec = currentTime.Second;
hourDeg = hour%12 * 30 + min * 0.5;
minDeg = min * 6;
secDeg = sec * 6;
// Remove & Add
myCanvas.Children.Remove(hourHand);
RotateTransform hourRt = new RotateTransform(hourDeg);
hourRt.CenterX = hourHand.X1;
hourRt.CenterY = hourHand.Y1;
hourHand.RenderTransform = hourRt;
myCanvas.Children.Add(hourHand);
myCanvas.Children.Remove(minHand);
RotateTransform minRt = new RotateTransform(minDeg);
minRt.CenterX = minHand.X1;
minRt.CenterY = minHand.Y1;
minHand.RenderTransform = minRt;
myCanvas.Children.Add(minHand);
myCanvas.Children.Remove(secHand);
RotateTransform secRt = new RotateTransform(secDeg);
secRt.CenterX = secHand.X1;
secRt.CenterY = secHand.Y1;
secHand.RenderTransform = secRt;
myCanvas.Children.Add(secHand);
Ellipse center = new Ellipse();
center.Width = 20;
center.Height = 20;
center.Margin = new Thickness(myCanvas.Width / 2 - center.Width / 2);
center.Stroke = Brushes.DarkOliveGreen;
center.StrokeThickness = 2;
center.Fill = Brushes.Chocolate;
myCanvas.Children.Add(center);
}
void dt_Tick(object sender, EventArgs e)
{
getCurrentTime();
}
}
}
C# WPF에서의 Graphics와 Multimedia의 처리에 대해서는 아래의 링크를 참조하기 바란다. http://msdn.microsoft.com/en-us/library/ms742562.aspx
Shape의 Transform에 대해서는 아래의 링크를 참조하기 바란다.
http://msdn.microsoft.com/en-us/library/ms747393.aspx#transforms
The Transform class provides the means to transform shapes in a two-dimensional plane. The different types of transformation include rotation (RotateTransform), scale (ScaleTransform), skew (SkewTransform), and translation (TranslateTransform).
BeeEye Dmu
'C# WPF' 카테고리의 다른 글
Analog Clock in C# WPF(아날로그 시계) - 3 (0) | 2013.10.18 |
---|---|
Analog Clock in C# WPF(아날로그 시계) - 2 (0) | 2013.10.18 |
C# WPF 계산기 (0) | 2013.10.02 |
Visual Studio 2012와 2010의 차이점 (0) | 2013.07.10 |
Delegate (0) | 2013.07.08 |