.NET CORE로 스탑워치를 만드는 방법은 여러가지가 있습니다. 여기서는 DispatcherTimer 와 Stopwatch 클래스로 만들어 보겠습니다. Visual Studio Code로 만들어 보겠습니다. (Visual Studio 도 상관없음)
먼저 NETCORE로 WPF 프로젝트를 생성합니다. WPF의 설치와 프로그램은 아래 게시물을 참고합니다.
C# WPF 개요 - 윈도우 GUI - Hello World (.NET CLI / Visual Studio Code 사용) - WPF 사용법 1
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" x:Name="tb" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" >
Hello WPF!
</TextBlock>
<Button Grid.Row="1" Grid.Column="0" Click="Button_Start">
Start
</Button>
<Button Grid.Row="1" Grid.Column="1" Click="Button_Stop">
Stop
</Button>
<Button Grid.Row="1" Grid.Column="2" Click="Button_Reset">
Reset
</Button>
</Grid>
간단하게 그리드 레이아웃으로 필요한 Component 를 넣습니다. 스탑워치니까 TextBlock 에 Button 이 들어갑니다. Button 은 Start, Stop, Reset 세개 기능이 필요합니다.
Button 의 Click 은 클릭했을 때 실행되는 함수 이름입니다. 그리드 디자인 적인 부분은 규칙을 알면 어렵지 않은데 잘 모른다면 아래의 포스팅을 참고합니다. 그리드 컨트롤 레이아웃 정도만 알아도 모양 디자인하는게 어렵진 않습니다. Visual Studio 에는 시각화 툴이 있어서 더 편리한데 개인적으로는 코드로 쓰는 것을 좋아해서 xaml을 직접 치기도 합니다. 자신에게 맞는 방법을 선택하도록 합니다.
Grid Control(그리드 컨트롤) 레이아웃 Xaml - C# WPF 사용법 2 (tistory.com)
public MainWindow()가 들어가는 C# 소스코드입니다. Stopwatch 클래스와 DispatcherTimer 를 사용하여 만들었습니다. (WPF라이브러리의 싱글쓰레드이다)
using System;
using System.Windows;
using System.Diagnostics;
using System.Windows.Threading;
namespace dotnet
{
public partial class MainWindow : Window
{
Stopwatch sw = new Stopwatch();
public MainWindow()
{
InitializeComponent();
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = TimeSpan.FromMilliseconds(1);
dt.Tick += dtTicker;
dt.Start();
}
private void dtTicker(object sender, EventArgs e)
{
if(tb != null){
tb.Text = string.Format("{0:hh\\:mm\\:ss\\:fff}", sw.Elapsed);
}
}
private void Button_Start(object sender, RoutedEventArgs e)
{
sw.Start();
}
private void Button_Stop(object sender, RoutedEventArgs e)
{
sw.Stop();
}
private void Button_Reset(object sender, RoutedEventArgs e)
{
sw.Reset();
}
}
}
Stopwatch 의 메소드가 편리해서 딱히 설명이 필요없을 정도입니다. 각 버튼에 메소드를 매치시키면 됩니다. Stopwatch 클래스의 Elapsed 에는 Start() 이후 카운트된 시간이 기록되 있습니다. 포맷을 하지 않으면 길으니까 string.Format 으로 좀 줄여줍니다. format은 초가 60초 분이 60분 시간이 24시간 단위로 도는데 직접 format을 만들 수도 있겠지요. (예를 들어 분과 초만 표시되도록, 100분, 1000분이 나오도록) 하지만 귀찮으니까 그냥 기본 포맷도 괜찮은 것 같습니다.
DispatcherTimer 의 Interval은 Timespan의 밀리초를 적용하면 1000분의1초 단위로 실행되는데, 만약 1초단위로 타이머를 작동하고 싶다면 1000을 넣으면 됩니다. 위의 dtTicker 는 1초에 1000번 실행하고 있습니다. 1000분의 1초가 너무 많은 것 같으면 100분의 1초로 실행합니다.
dt.Interval = TimeSpan.FromMilliseconds(10);
tb.Text = string.Format("{0:hh\\:mm\\:ss\\:ff}", sw.Elapsed);
이렇게 바꿔주면 됩니다. 인간 눈이 1000분의 1초는 분간이 안가기 때문에 100분의 1 정도가 적당합니다. 모니터도 주사율이 144hz 정도 보는 시대니까 100분의 1초가 맞을 겁니다.
타이머와 시간을 사용할 줄 알면 편리한 것들을 만들어 낼 수 있습니다.
코드가 어렵지 않으니 C#으로 한번 만들어 보는 것을 추천합니다.