Style의 EventSetter를 이용하여 이벤트에 대한 응답 핸들러 메소드를 지정할 수 있다.
Setter가 Style의 자식중 대체로 이용 되지만 라우팅된 특정 이벤트(버튼의 Click등)의 이벤트핸들러를 설정하기 위해서는 EventSetter 엘리먼트를 이용할 수 있는데 다수의 엘리먼트에서 이벤트를 공유할 수 있다.
[실습]
아래 예제에서 3개의 버튼이 존재하는데 각 버튼은 자체적인 클릭 이벤트를 가지고 있어 클릭을 하면 그 이벤트 핸들러가 실행되고 그 이후 Style에 적용된 EventSetter가 적용되어서 빨강색 브러시가 적용되어 배경이 붉은색으로 변경이 됩니다. 하지만 Button3는 e.handled=true가 되어 이벤트 라우팅이 중단되어 EventSetter의 핸들러 메소드가 호출되지 않는다.
이벤트 라우팅은 “어떤 이벤트가 엘리먼트의 하위 또는 상위로 전달되는 것”을 이야기 하며 WPF에서 광범위하게 이용되는 방법이다.
이벤트 라우팅은 세가지로 분류할 수 있는데 이벤트가 발생했을 때 현재 엘리먼트에서 상위로 올라가면서 이벤트가 전달되는 경우를 버블링 이벤트(Bubbleing Event)라고 하고 반대로 자식 엘리먼트로 전달되는 경우를 터널링(Tunneling Event) 이벤트라고 한다. 하나의 엘리먼트에서만 발생하게 된다면 다이렉트 이벤트(Direct Event)라고 한다. 터널링 이벤트의 경우 접두사로 preview를 붙인다. PreviewMouseDown, PreviewDragDown 등으로 쓰여지는 것들을 Tunneling 이벤트라고 이해하면 된다.
터널링 이벤트는 최상위 부모 이벤트부터 자기자신까지 이벤트가 진행되는 것인데, 이벤트가 자식 요소에게 전달되기 전에 부모의 이벤트가 먼저 호출되므로 부모 이벤트가 먼저 호출할 수 있는 기회를 제공한다. 자식의 이벤트 발생을 막거나 자식이벤트 처리 전에 부모 요소가 무엇인가 수행할 필요가 있는 경우에 유용한다.
이벤트 핸들러 메소드는 RoutedEventArgs 매개변수를 가지는데 Source 속성을 통해 실제 이벤트를 발생시킨 요소에 대한 참조를 제공한다. 이 속성은 여러 요소에서 발생한 이벤트를 동일한 방법으로 처리하고자 할 때 특히 유용하다.
Button, StackPanel, Window의 Click 이벤트는 모두 첫 번째 인자는 이벤트 퍼블리셔를 가리키는 object 타입을, 두 번째 인자로 System.Windows.RoutedEventArgs 타입의 인자로 전달하게 된다.
예제에서 버튼을 클릭시 클릭 이벤트가 버블링 되어 상위 객체로 라우팅 된다. 즉 버튼 클릭 이벤트 실행 -> 스택 패널 클릭 이벤트 실행 -> 윈도우 클릭 이벤트 순서로 된다.
실행화면
상위 객체로 라우팅 되는 것을 막으려면 RoutedEventArgs의 Handled 속성을 true로 설정하면 된다. 버튼 클릭 이벤트에 “e.Handled = true” 라고 하면 버튼까지만, 스택 패널 클릭 이벤트에 “e.Handled = true” 라고 한다면 스택 패널 까지만 이벤트가 전달된다.