WPF 에서 중요한 개념 중 하나는 Routed Event 이다.


간단히 버튼을 클릭했을 때 발생하는 Click 이벤트, 혹은 패널을 클릭했을 때 발생하는 MouseDown, MouseUp 등의 것들이 Routed Event 에 포함된다.

하지만 꼭 엘리먼트에서만 발생하는 것은 아니고 코드 상에서 임의로 발생시킬 수도 있기 때문에, MSDN의 정의를 참조하도록 하자.


. 기능 측면의 정의 : Routed Event 는 이벤트를 발생시킨 특정 개체 뿐 아니라 엘리먼트 트리의 여러 리스너(listener)의 핸들러(handler)를 호출할 수 있는 이벤트 형식이다.

. 구현 측면의 정의 : Routed Event 는 RoutedEvent 클래스 객체의 지원을 받으며, WPF의 이벤트 시스템에 의해 처리된다.


WPF에는 Routed Event 를 두가지로 분류할 수 있다. 이는 버블링(Bubbling) 과 터널링(Tunneling) 이다.

버블링 이벤트는 발생한 이벤트 소스의 이벤트 처리기가 호출되고, 이후 트리 루트에 도달할 때까지 부모 엘리먼트로 라우팅하며, 일반적으로 사용된다.

반면 터널링 이벤트는 엘리먼트의 트리 루트(root)의 이벤트 처리기를 호출하고 자식 엘리먼트로 라우팅하며 이벤트 소스 엘리먼트까지 전달된다.

일반적으로 Tunneling 이벤트의 경우 접두사로 Preview가 붙고, PreviewMouseDown, PreviewDragDown 등으로 쓰여져 있으면 이를 Tunneling 이벤트라고 이해하면 된다.



- 상기 그림은 MSDN에서 퍼옴


위의 그림에서 element#2에서 이벤트가 발생했다고 하면 버블링, 터널링 이벤트가 발생하는 순서는 다음과 같다.


1. PreviewMouseDown (tunnel) on root element.

2. PreviewMouseDown (tunnel) on intermediate element #1.

3. PreviewMouseDown (tunnel) on source element #2.

4. MouseDown (bubble) on source element #2.

5. MouseDown (bubble) on intermediate element #1.

6. MouseDown (bubble) on root element.



* 이 때 더이상 이벤트가 라우팅 되지 않도록 하는 방법이 있다.

모든 라우팅된 이벤트는 공통 이벤트 데이터의 기본 클래스인 RoutedEventArgs를 공유한다. 이 클래스에는 Handled라는 속성이 존재하는데, 이 속성은 기본으로 false로 되어 있다. 한 이벤트 처리기에서 이 속성, 즉 RoutedEventArgs.Handled 를 true라고 설정하면 이 이벤트는 처리된 것으로 되어 더이상 라우팅 되지 않는다.


즉 위의 그림의 구조에서 3번 이벤트에 대한 이벤트 핸들러에서 e.Handled = true; 라는 문장을 써주면 4, 5, 6번의 이벤트는 라우팅되지 않는다.


+ Recent posts