WPF에서 이벤트의 라우팅을 공부하면서 Event에 대해서 정리를 해보자는 마음이 생겼다. 먼저 닷넷 2.0을 기준으로 이벤트에 대해서 정리를 해보고 다음에 기회가 되면 WPF의 이벤트 라우팅에 대해서 써보겠다.
정리하는 내용은 MSDN을 보고 내가 이해한 것을 바탕으로 작성했다.
http://msdn.microsoft.com/ko-kr/library/awbftdfh(VS.80).aspx
1. Event의 개요
1) Event 게시
2) Event 구독
3) Event 처리
여기서 1)를 수행하는 클래스를 게시자라고 하며 2), 3)를 수행하는 클래스를 구독자라고 한다. 게시자나 구독자라는 용어보다는 위의 단계에 대한 이해하는 것이 더 중요하다.
간단한 예를 들어서 위의 단계를 적용시켜 보자. 폼에 버튼을 하나 올려놓고 버튼을 클릭(두번클릭)하면 Click 이벤트가 자동으로 구독(InitializeComponent())이 되고 비하인드 코드에 이벤트가 등록된 이후의 어떤식으로 이벤트를 처리할 것인지를 작성할 수 있는 메소드가 자동으로 만들어진다.
MSDN에서 Event에 대한 개요 중 첫번째 문장이다.
게시자는 이벤트가 발생하는 시기를 결정하고 구독자는 이벤트에 대한 응답으로 수행되는 동작을 결정합니다. |
=> 위의 예에서 보면 버튼(게시자)에서 Click이라는 이벤트가 발생하는 시기(말 그대로 Click하는 순간)를 결정하기 위해 Event를 게시하였기 때문에 Click 이벤트를 사용할 수 있다. 폼(구독자)에 올려진 버튼(게시자)의 Click 이벤트를 버튼을 더블클릭(구독)하고 Click 이벤트가 발생할 때의 수행되는 동작(핸들러)을 처리할 수 있다.
2. Event의 구독 및 취소
먼저 이미 게시되어 있는 Event를 구독하여 보자. 1번에서 처럼 버튼을 더블클릭함으로써 자동으로 이벤트를 구독할 수 있다. 하지만 여기서는 프로그래밍적으로 구독을 해보도록 하자.
public Form1() { InitializeComponent(); Load += new EventHandler(Form1_Load); } void Form1_Load(object sender, EventArgs e) { //이벤트에 대한 응답으로 수행되는 동작 |
private void button1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { // 왼쪽 버튼을 눌렀을 경우의 동작 시키고 싶은 코드 } } |
3. Event의 게시
Event를 게시하는 게시자 클래스이다. 델리게이트로 연결하는 부분과 닷넷 프레임워크 지침에 따른 것을 제너릭 부분을 제거하고 EventHandler부분에 대한 이해를 돕기 위해서 약간 수정하였다.
class Publisher { public delegate void CustomEventHandler(object sender, EventArgs e); public event CustomEventHandler RaiseCustomEvent; public void DoSomething() { OnRaiseCustomEvent(new EventArgs()); } { CustomEventHandler handler = RaiseCustomEvent; if (handler != null) { handler(this, e); } } } |
OnRaiseCustomEvent()를 살펴보면 꼭 이렇게 할 필요는 없지만 닷넷 프레임워크 지침에 따른거니 표준정도라고 생각하고 보자. 좀 더 이해하기 쉽게 바꾸면 다음과 같다.
protected virtual void OnRaiseCustomEvent(EventArgs e) { { RaiseCustomEvent(this, e); } } |
OnRaiseCustomEvent()는 virtual로 선언될 것을 볼 수 있다. 이 메소드는 재정의가 가능하다는 의미이고 많이 낯이 익는다. On~으로 시작하는 메소드는 바로 이벤트보다 먼저 실행이 되는 메소드인 것이다. 그래서 우리가 이벤트를 구독하지 않고 On~메소드를 재정의하여서도 이벤트를 사용할 수 있는 것이다. 2번에서 구독해본 폼의 Load이벤트를 override 키워드와 On으로 시작하는 메소드중 OnLoad()를 찾으면 아래와 같은 코드를 자동으로 만들어준다.
protected override void OnLoad(EventArgs e) { base.OnLoad(e); //이벤트에 대한 응답으로 수행되는 동작 |
마지막으로 게시자에서는 이벤트가 일어나는 시점을 결정한다고 하였는데 DoSomething()가 바로 그 역할을 하는 메소드이다. 앞에서도 말했듯이 새롭게 이벤트에 대응되는 메소드인 OnRaiseCustomEvent()를 여기서 호출을 해주고 있는 것을 알 수 있다.