ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • WPF 시계만들기 (Rotation 사용)
    C# 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]);
                }
            }
        }
    }

    전체코드

     

    실행결과

     

    'C#' 카테고리의 다른 글

    WPF 시계만들기  (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

    댓글

Designed by Tistory.