-
디자인 디자인
<Window x:Class="_044_Clock.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:_044_Clock" mc:Ignorable="d" Title="WPF Clock" Height="350" Width="350"> <StackPanel> <Menu> <MenuItem Header="보기"> <MenuItem Header="아날로그 시계" Click="aClock_Click"/> <MenuItem Header="디지털 시계" Click="dClock_Click"/> <Separator/> <MenuItem Header="종료" Click="Exit_Click"/> </MenuItem> <MenuItem Header="옵션"> <MenuItem Header="초 단위" Click="Sec_Click"/> <MenuItem Header="밀리초 단위" Click="MS_Click"/> </MenuItem> </Menu> <Grid Margin="10"> <Canvas x:Name="canvas1" Width="250" Height="250"> <Ellipse x:Name="aClock" Width="250" Height="250" /> </Canvas> <TextBlock x:Name="txtDate" FontFamily="맑은 고딕" FontSize="15" Margin="15 50" Foreground="OrangeRed"/> <TextBlock x:Name="txtTime" FontFamily="DokChampa" FontSize="40" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="RoyalBlue"/> </Grid> </StackPanel> </Window>
StackPanel을 틀로 사용해 만들었고 시계를 그려주기위해 Canvas를 사용하였다.
Menu를 통해 보기와 옵션을 넣어주었다.
Main및 timerSetting()
public partial class MainWindow : Window { bool aClock_Flag = true; Point center; double radius; int hourHand; int minHand; int secHand; bool ms_flag = false; DispatcherTimer timer = new DispatcherTimer(); public MainWindow() { InitializeComponent(); aClockSetting(); timerSetting(); } private void timerSetting() { timer.Interval = new TimeSpan(0,0,0,0,10); //0.01초에 한번 timer.Tick += Timer_Tick; timer.Start(); }
DispatcherTimer timer = new DispatcherTimer(); 를 사용하여 시계를 구현하였다. Dispatcher를 사용하기 위해서
using System.Windows.Threading; 추가해주었다.
aClockSetting()
private void aClockSetting() { center = new Point(canvas1.Width / 2, canvas1.Height / 2); radius = canvas1.Width / 2; hourHand = (int)(radius * 0.45); minHand = (int)(radius * 0.55); secHand = (int)(radius * 0.65); }
사실 구현한 알고리즘 자체는 저번에 winForm을 구현했을때와 같다.
Timer_Tick()
private void Timer_Tick(object sender, EventArgs e) { DateTime c=DateTime.Now; canvas1.Children.Clear(); //현재 화면 지우기 if (aClock_Flag) { DrawClockFace(); double radHr = (c.Hour % 12 + c.Minute / 60) * 30 * Math.PI / 180; double radMin = (c.Minute + c.Second / 60) * 6 * Math.PI / 180; double radSec = (c.Second * 6) * Math.PI / 180; DrawHands(radHr, radMin, radSec); } else { txtDate.Text = DateTime.Today.ToString("D"); if (ms_flag) { txtTime.Text = string.Format("{0:D2}:{1:D2}:{2:D2}:{3:D3}", c.Hour, c.Minute, c.Second,c.Millisecond); } else { txtTime.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", c.Hour, c.Minute, c.Second); } } }
윈폼과 마찬가지로 aClock_Flag은 아날로그 시계와 디지털 시계를 구별하기 위해 사용하였다.
DrawClockFace()
private void DrawClockFace() { aClock.Stroke = Brushes.LightSteelBlue; aClock.StrokeThickness = 30; canvas1.Children.Add(aClock); }
저기 aClock은 xaml에서 구현한 Ellipse의 이름이다.
Children.Add를 통해 그려준다.
DrawHands()
private void DrawHands(double radHr, double radMin, double radSec) { DrawLine(0, 0, (int)(secHand * Math.Sin(radSec)), (int)(secHand * Math.Cos(radSec)), Brushes.OrangeRed, 4); DrawLine(0, 0, (int)(minHand * Math.Sin(radMin)), (int)(minHand * Math.Cos(radMin)), Brushes.Blue, 4); DrawLine(0, 0, (int)(hourHand * Math.Sin(radHr)), (int)(minHand * Math.Cos(radHr)), Brushes.Green, 4); int coreSize = 16; Ellipse core = new Ellipse(); core.Margin = new Thickness(center.X - coreSize / 2, center.Y - coreSize / 2, 0, 0); core.Stroke = Brushes.SteelBlue; core.StrokeThickness = 3; core.Fill = Brushes.LightSteelBlue; core.Width = coreSize; core.Height = coreSize; canvas1.Children.Add(core); }
알고리즘은 전과 동일하고 시계배꼽을 만들어주기위해 Ellipse를 core를 생성 시계 정중앙으로 설정하고 Stroke를 SteelBrue로 굵기는 3으로 설정하였고 색은 LightSteelBlue를 사용하였다.
여기서도 Children.Add를 사용하여 그려주었다.
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 _044_Clock { public partial class MainWindow : Window { bool aClock_Flag = true; Point center; double radius; int hourHand; int minHand; int secHand; bool ms_flag = false; DispatcherTimer timer = new DispatcherTimer(); public MainWindow() { InitializeComponent(); aClockSetting(); timerSetting(); } private void timerSetting() { timer.Interval = new TimeSpan(0,0,0,0,10); //0.01초에 한번 timer.Tick += Timer_Tick; timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { DateTime c=DateTime.Now; canvas1.Children.Clear(); //현재 화면 지우기 if (aClock_Flag) { DrawClockFace(); double radHr = (c.Hour % 12 + c.Minute / 60) * 30 * Math.PI / 180; double radMin = (c.Minute + c.Second / 60) * 6 * Math.PI / 180; double radSec = (c.Second * 6) * Math.PI / 180; DrawHands(radHr, radMin, radSec); } else { txtDate.Text = DateTime.Today.ToString("D"); if (ms_flag) { txtTime.Text = string.Format("{0:D2}:{1:D2}:{2:D2}:{3:D3}", c.Hour, c.Minute, c.Second,c.Millisecond); } else { txtTime.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", c.Hour, c.Minute, c.Second); } } } private void DrawHands(double radHr, double radMin, double radSec) { DrawLine(0, 0, (int)(secHand * Math.Sin(radSec)), (int)(secHand * Math.Cos(radSec)), Brushes.OrangeRed, 4); DrawLine(0, 0, (int)(minHand * Math.Sin(radMin)), (int)(minHand * Math.Cos(radMin)), Brushes.Blue, 4); DrawLine(0, 0, (int)(hourHand * Math.Sin(radHr)), (int)(minHand * Math.Cos(radHr)), Brushes.Green, 4); int coreSize = 16; Ellipse core = new Ellipse(); core.Margin = new Thickness(center.X - coreSize / 2, center.Y - coreSize / 2, 0, 0); core.Stroke = Brushes.SteelBlue; core.StrokeThickness = 3; core.Fill = Brushes.LightSteelBlue; core.Width = coreSize; core.Height = coreSize; canvas1.Children.Add(core); } private void DrawLine(int x1, int y1, int x2, int y2, Brush brush, int thick) { Line line = new Line(); line.X1 = x1; line.Y1 = y1; line.X2 = x2; line.Y2 = -y2; line.Stroke = brush; line.StrokeThickness = thick; line.Margin = new Thickness(center.X, center.Y, 0, 0); line.StrokeEndLineCap=PenLineCap.Round; canvas1.Children.Add(line); } private void DrawClockFace() { aClock.Stroke = Brushes.LightSteelBlue; aClock.StrokeThickness = 30; canvas1.Children.Add(aClock); } private void aClockSetting() { center = new Point(canvas1.Width / 2, canvas1.Height / 2); radius = canvas1.Width / 2; hourHand = (int)(radius * 0.45); minHand = (int)(radius * 0.55); secHand = (int)(radius * 0.65); } private void aClock_Click(object sender, RoutedEventArgs e) { aClock_Flag = true; txtDate.Text = ""; txtTime.Text = ""; } private void dClock_Click(object sender, RoutedEventArgs e) { aClock_Flag = false; } private void Exit_Click(object sender, RoutedEventArgs e) { this.Close(); } private void Sec_Click(object sender, RoutedEventArgs e) { timer.Interval = new TimeSpan(0, 0, 0, 1); ms_flag = false; } private void MS_Click(object sender, RoutedEventArgs e) { timer.Interval = new TimeSpan(0, 0, 0,0, 10); ms_flag = true; } } }
전체코드이다.
실행결과 실행결과 'C#' 카테고리의 다른 글
WPF 시계만들기 (Rotation 사용) (0) 2022.06.16 WPF Splash (0) 2022.06.01 WPF LOGIN (0) 2022.05.25 ACCESS를 사용한 DB연결 -2 (0) 2022.05.11 ACCESS를 사용한 DB연결 -1 (0) 2022.05.04