본문 바로가기

개발새발 개발자/C#

[C# GUI 프로그래밍] 타이머 컨트롤 이벤트 처리

시간에 대한 이벤트를 주려면 Timer가 필요하다. 도구 상자의 Timer를 form에 추가해준다.


하지만 그렇다고 해서 화면상에 타이머가 돌아가는 모습이 보이는 건 아니다. 그런 건 그래픽을 따로 띄워주는 것이지 실제로 눈으로 보여주지는 않는다. 단지 정해놓은 시간 주기로 이벤트를 발생시키는 컨트롤이다.


개수는 컴퓨터가 허용하는 한계까지 계속 추가할 수 있다. 너무 많이 사용하는 것은 좋지 않다.


- timer 속성 정하기

Enabled: True로 설정해 form이 시작 하자마자 타이머를 사용할 수 있도록 한다.

Interval: 타이머 이벤트 실행 간격을 ms(밀리 sec) 단위로 설정한다. 100ms = 0.1sec이다.


타이머 예시

타이머로 전자 시계를 만들어보자. 사실 이 프로그램은 라벨이나 텍스트 박스로 만들면 훨씬 쉽다. 하지만 리스트 박스에 add, remove 구현을 활용하기 위해 리스트 박스로 구성했다.


필요한 것은 다음과 같다.

1. 분과 초를 기록할 변수

2. 초를 증가시키는 이벤트: Timer 이벤트가 발생할 때 마다 초에 대한 변수값을 증가시킨다.

3. 분을 증가시키는 이벤트: 초가 50이 되면 1을 증가시키고 초는 0으로 바꿔준다.

listBoxSecond.Items.Remove(Second)    // 계속 Add하면 새로운 행이 추가되므로 먼저 이전 값을 삭제한다.

Second++;        // 초를 증가시킴

listBoxSecond.Items.Add(Second);        // 리스트 박스에 시간 표시

쓰고 나서 지우면 글자가 순간적으로 사라지는 것처럼 보이므로 쓰기 직전에 지워주는 것이 좋다.


private void timer1_Tick(object sender, EventArgs e) { listBoxSecond.Items.Remove(Second);    // 지웠다가 Second++;        // 초를 증가 시키고

listBoxSecond.Items.Add(Second);  // 다시 쓴다.

if (Second == 60)    // 초가 60이 되면 { Second = 0;    // 다시 0으로 바꾸고 listBoxMinute.Items.Remove(Minute);        // 분을 지웠다가 Minute++;        // 증가시켜서 listBoxMinute.Items.Add(Minute);    // 넣는다. }

}

대충 보면 맞는 것 같지만 사실 오류가 몇 가지 있다. 


1. Add가 증가시킨 다음 바로 나오기 때문에 60일 경우 그대로 출력된다. 그리고 다시 0으로 바뀌므로 결국 61초를 세게 된다.

2. if 문에서 Second 값이 0인 것을 보낸 뒤, 첫 줄로 돌아가서 Second=0인 변수를 Remove 해야 한다. 하지만 지금은 60으로 되어 있으므로 지울 수가 없다. 따라서 분이 증가할 때 마다 초에 있는 리스트 박스에 행이 하나씩 늘어난다.

private void timer1_Tick(object sender, EventArgs e) { listBoxSecond.Items.Remove(Second);    // 지웠다가 Second++;        // 초를 증가 시키고 if (Second == 60) { Second = 0; listBoxMinute.Items.Remove(Minute); Minute++; listBoxMinute.Items.Add(Minute); } listBoxSecond.Items.Add(Second);   // 이때 바꿔준다. }

이렇게 순서를 바꿔주면 정상적으로 작동한다. 두 코드를 비교해보고 싶으면 interval을 100정도로 낮추고 보면 된다.


if(Second%2==1) { listBoxColon.Items.Add(":"); } else { listBoxColon.Items.Remove(":"); }

이제 콜론을 깜빡여보자. 1초마다 깜빡이게 하고 싶으면, 초를 2로 나눠서 나머지가 1일 때는 Add하고, 아닐때는 Remove하면 된다.


public partial class Form1 : Form {

       // 필요한 인스턴스 변수를 선언해주고 private int Second; private int Minute; public Form1() { InitializeComponent();

           

           // 0으로 초기화 한 뒤 Second = 0; Minute = 0;


           // 초 값을 리스트 박스에 넣어준다. listBoxSecond.Items.Add(Second); }         

       // 타이머 이벤트 발생 private void timer1_Tick(object sender, EventArgs e) { listBoxSecond.Items.Remove(Second); Second++; if (Second == 60) { Second = 0; listBoxMinute.Items.Remove(Minute); Minute++; listBoxMinute.Items.Add(Minute); }


           // 콜론 깜빡임 if(Second%2==1) { listBoxColon.Items.Add(":"); } else { listBoxColon.Items.Remove(":"); }


           // 최종적으로 초 값을 갱신한다. listBoxSecond.Items.Add(Second); } }

전체적인 코드 구조는 이렇다.