WPF : 타이머 만들기

2026. 4. 23. 22:24·FRAMEWORK/WPF

1. 사전 준비사항

- MVVM 구조에 대한 이해

더보기

2026.04.23 - [C#/Study] - WPF : MVVM(Model - View - ViewModel)

 

WPF : MVVM(Model - View - ViewModel)

1. MVVM [View (XAML)] ↓ Binding[ViewModel] ↓ 데이터 처리[Model]2. Model(Data)데이터UI 를 알 필요없음로직 Xpublic class Car{ public string Name { get; set; } public int Speed { get; set; }}3. ViewModel 1) 역할UI에 보여줄 데이터

marin0806.tistory.com

 

- DispatcherTimer Class(타이머 클래스)

더보기

※ DispatcherTimer

- UI 스레드에서 Tick 이벤트를 실행하는 타이머

private DispatcherTimer _timer;

 

1. Interval(TimeSpan Type)

_timer.Interval = TimeSpan.FromSeconds(1);

> 1초마다 Tick 이벤트를 발생시키겠다.

 

2. Tick

void Timer_Tick(object sender, EventArgs e)
{
    // Logic
}

_timer.Tick += Timer_Tick;

> Interval 마다 실행되는 이벤트(메서드)

 

3. Start

_timer.Start();

> 타이머 시작

 

4. Stop

_timer.Stop();

> 타이머 멈춤

 

5. IsEnabled

_timer.IsEnabled
// true or false 반환

> 현재 실행 상태 확인(true/false)


2. Solution(솔루션 구조)

① Commands : Commands\RelayCommands.cs

② ViewModels : ViewModels\MainViewModels.cs

③ Views : Views\MainWindow.xaml(MainWindow.xaml.cs)


3. RelayCommands 구현

using System;
using System.Windows.Input;


public class RelayCommand : ICommand
{
    private readonly Action _execute;
    private readonly Func<bool> _canExecute;
    public RelayCommand(Action execute, Func<bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;
    public void Execute(object parameter) => _execute();

    public event EventHandler CanExecuteChanged;

    public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

> 이전 글과 구조는 같다.


4. MainViewModel 구현

1) 전체구현

using System;
using System.ComponentModel;
using System.Windows.Threading;
using System.Windows.Input;
using Microsoft.VisualBasic;

public class MainViewModel : INotifyPropertyChanged
{
    private DispatcherTimer _timer;

    private string _currentTime;
    public string CurrentTime
    {
        get => _currentTime;
        set
        {
            _currentTime = value;
            OnPropertyChanged(nameof(CurrentTime));
        }
    }

    private TimeSpan _stopwatchTime;
    public string StopwatchTime => _stopwatchTime.ToString(@"hh\:mm\:ss");

    private bool _isRunning;

    public ICommand StartCommand { get; }
    public ICommand StopCommand { get; }
    public ICommand ResetCommand { get; }

    public MainViewModel()
    {
        _timer = new DispatcherTimer();
        _timer.Interval = TimeSpan.FromSeconds(1);
        _timer.Tick += Timer_Tick;
        _timer.Start();

        StartCommand = new RelayCommand(Start);
        StopCommand = new RelayCommand(Stop);
        ResetCommand = new RelayCommand(Reset);
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        CurrentTime = DateTime.Now.ToString("HH:mm:ss");

        if (_isRunning)
        {
            _stopwatchTime = _stopwatchTime.Add(TimeSpan.FromSeconds(1));
            OnPropertyChanged(nameof(StopwatchTime));
        }
    }

    private void Start()
    {
        _isRunning = true;
    }
    private void Stop()
    {
        _isRunning = false;
    }
    private void Reset()
    {
        _isRunning = false;
        _stopwatchTime = TimeSpan.Zero;
        OnPropertyChanged(nameof(StopwatchTime));
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

 

2) 설명

더보기

1. Data Binding

public string CurrentTime
{
    get => _currentTime;
    set
    {
        _currentTime = value;
        OnPropertyChanged(nameof(CurrentTime));
    }
}

public string StopwatchTime => _stopwatchTime.ToString(@"hh\:mm\:ss");

> 바인딩 될 데이터들

 

2. Command Binding

public ICommand StartCommand { get; }
public ICommand StopCommand { get; }
public ICommand ResetCommand { get; }

> 바인딩 될 명령들

 

3. Command Mathod

private void Start()
{
    _isRunning = true;
}
private void Stop()
{
    _isRunning = false;
}
private void Reset()
{
    _isRunning = false;
    _stopwatchTime = TimeSpan.Zero;
    OnPropertyChanged(nameof(StopwatchTime));
}

> 바인딩 된 명령들(Command)의 Execute로 호출될 메서드들

 

4. MainViewModel 생성자

public MainViewModel()
{
    _timer = new DispatcherTimer();
    _timer.Interval = TimeSpan.FromSeconds(1);
    _timer.Tick += Timer_Tick;
    _timer.Start();

    StartCommand = new RelayCommand(Start);
    StopCommand = new RelayCommand(Stop);
    ResetCommand = new RelayCommand(Reset);
}

> Command 들을 RelayCommand 형 객체로 동적생성

 

5. PropertyChangedEventHandler

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

> 데이터 변경에 따라 View 에게 알림을 주기위한 PropertyChangeEventHandler


5. MainWindow.xaml 구현

1) 전체구현

<Window x:Class="ClockTimerApp.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:ClockTimerApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    
    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
        <TextBlock Text="{Binding CurrentTime}"
                   FontSize="30"
                   HorizontalAlignment="Center"
                   Margin="10"/>
        <TextBlock Text="{Binding StopwatchTime}"
                   FontSize="25"
                   HorizontalAlignment="Center"
                   Margin="10"/>

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Content="Start" Command="{Binding StartCommand}" Margin="5"/>
            <Button Content="Stop" Command="{Binding StopCommand}" Margin="5"/>
            <Button Content="Reset" Command="{Binding ResetCommand}" Margin="5"/>
        </StackPanel>
    </StackPanel>
    
</Window>

 

2) 설명

더보기

1. Data Binding

<TextBlock Text="{Binding CurrentTime}"
           FontSize="30"
           HorizontalAlignment="Center"
           Margin="10"/>
<TextBlock Text="{Binding StopwatchTime}"
           FontSize="25"
           HorizontalAlignment="Center"
           Margin="10"/>

> CurrentTime, StopwatchTime 바인딩

 

2) CommandBinding

<Button Content="Start" Command="{Binding StartCommand}" Margin="5"/>
<Button Content="Stop" Command="{Binding StopCommand}" Margin="5"/>
<Button Content="Reset" Command="{Binding ResetCommand}" Margin="5"/>

> Start, Stop, Reset 바인딩

5.1 View - ViewModel 연결

using System.Windows;

namespace ClockTimerApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }
    }
}
DataContext = new MainViewModel();

> View 는 MainViewModel 이라는 ViewModel 과 연결됨.


6. 구현 ScreenShot


7. 구현 Video

wpf 타이머.mp4
0.66MB

'FRAMEWORK > WPF' 카테고리의 다른 글

WPF : ViewModel - DI(의존성 주입)  (0) 2026.04.25
WPF : Model  (0) 2026.04.25
WPF : MVVM(Model - View - ViewModel)  (0) 2026.04.23
WPF : WPF 에 대하여  (0) 2026.04.22
'FRAMEWORK/WPF' 카테고리의 다른 글
  • WPF : ViewModel - DI(의존성 주입)
  • WPF : Model
  • WPF : MVVM(Model - View - ViewModel)
  • WPF : WPF 에 대하여
m_Dev
m_Dev
  • m_Dev
    m_Dev
    m_Dev
  • 전체
    오늘
    어제
    • 분류 전체보기
      • MAIN STUDY
        • 정보보안
        • 빅데이터
        • 정보처리
        • 컴퓨터 구조
        • 기타
      • JOB
        • Study
        • Project
      • LMS 7
        • 개발일지
      • FRAMEWORK
        • Qt
        • MFC
        • Winform
        • WPF
        • MAUI
      • NETWORK
        • Study
        • Assignment
      • PYTHON
        • Set
        • Study
        • Assignment
        • Project
      • C
        • Set
        • Study
        • Assignment
        • Project
      • C++
        • Set
        • Study
        • Assignment
        • Project
      • C#
        • Set
        • Study
        • Assignment
        • Project
      • DATABASE
        • MySQL
        • SQLite
      • IDE
        • VisualStudioCode
        • VisualStudio
        • Pycharm
        • Colab
      • 기타
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
m_Dev
WPF : 타이머 만들기
상단으로

티스토리툴바