라우트된 이벤트 개요Routed Events Overview

이 항목에서는 WPF(Windows Presentation Foundation)Windows Presentation Foundation (WPF)에서 라우트된 이벤트의 개념을 설명합니다.This topic describes the concept of routed events in WPF(Windows Presentation Foundation)Windows Presentation Foundation (WPF). 이 항목에서는 라우트된 이벤트 용어를 정의하고, 라우트된 이벤트가 요소 트리를 통해 라우트되는 방식을 설명하고, 라우트된 이벤트를 처리하는 방법을 요약하고, 자체 사용자 지정 라우트된 이벤트를 만드는 방법을 소개합니다.The topic defines routed events terminology, describes how routed events are routed through a tree of elements, summarizes how you handle routed events, and introduces how to create your own custom routed events.

전제 조건Prerequisites

이 항목에서는 CLR (공용 언어 런타임) 및 개체 지향 프로그래밍에 대 한 기본 지식이 있다고 가정 하 고 요소 간의 WPFWPF 관계를 트리로 개념화 하는 방법에 대 한 개념을 설명 합니다.This topic assumes that you have basic knowledge of the common language runtime (CLR) and object-oriented programming, as well as the concept of how the relationships between WPFWPF elements can be conceptualized as a tree. 이 항목의 예제를 따르려면 XAML(Extensible Application Markup Language)Extensible Application Markup Language (XAML)을 이해하고 매우 기본적인 WPFWPF 애플리케이션 또는 페이지를 작성하는 방법을 알아야 합니다.In order to follow the examples in this topic, you should also understand XAML(Extensible Application Markup Language)Extensible Application Markup Language (XAML) and know how to write very basic WPFWPF applications or pages. 자세한 내용은 연습: 내 첫 번째 wpf 데스크톱 응용 프로그램 및 XAML 개요 (wpf)For more information, see Walkthrough: My first WPF desktop application and XAML Overview (WPF).

라우트된 이벤트란?What Is a Routed Event?

기능 또는 구현 측면에서 라우트된 이벤트를 살펴볼 수 있습니다.You can think about routed events either from a functional or implementation perspective. 사용자마다 더 유용하다고 생각하는 정의가 다르므로 여기에서는 두 가지 정의를 모두 제공합니다.Both definitions are presented here, because some people find one or the other definition more useful.

함수 정의: 라우트된 이벤트는 이벤트를 발생 시킨 개체 뿐만 아니라 요소 트리의 여러 수신기에서 처리기를 호출할 수 있는 이벤트 형식입니다.Functional definition: A routed event is a type of event that can invoke handlers on multiple listeners in an element tree, rather than just on the object that raised the event.

구현 정의: 라우트된 이벤트는 RoutedEvent 클래스의 인스턴스에서 지원 되 고 WPF(Windows Presentation Foundation)Windows Presentation Foundation (WPF) 이벤트 시스템에서 처리 되는 CLR 이벤트입니다.Implementation definition: A routed event is a CLR event that is backed by an instance of the RoutedEvent class and is processed by the WPF(Windows Presentation Foundation)Windows Presentation Foundation (WPF) event system.

일반적인 WPFWPF 애플리케이션에는 많은 요소가 포함됩니다.A typical WPFWPF application contains many elements. 코드로 만들어지든지, XAMLXAML에 선언되든지 관계없이 이러한 요소는 서로에 대한 요소 트리 관계로 존재합니다.Whether created in code or declared in XAMLXAML, these elements exist in an element tree relationship to each other. 이벤트 경로는 이벤트 정의에 따라 두 방향 중 하나로 이동할 수 있지만, 일반적으로 경로는 소스 요소부터 이동하여 요소 트리 루트(일반적으로 페이지 또는 창)에 도달할 때까지 요소 트리를 통해 위쪽으로 "버블링"됩니다.The event route can travel in one of two directions depending on the event definition, but generally the route travels from the source element and then "bubbles" upward through the element tree until it reaches the element tree root (typically a page or a window). 이전에 DHTML 개체 모델을 사용했다면 이 버블링 개념이 익숙할 것입니다.This bubbling concept might be familiar to you if you have worked with the DHTML object model previously.

다음 간단한 요소 트리를 살펴보세요.Consider the following simple element tree:

<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
  <StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler">
    <Button Name="YesButton" Width="Auto" >Yes</Button>
    <Button Name="NoButton" Width="Auto" >No</Button>
    <Button Name="CancelButton" Width="Auto" >Cancel</Button>

이 요소 트리는 다음과 같은 항목을 생성합니다.This element tree produces something like the following:

예, 아니요 및 취소 단추Yes, No, and Cancel buttons

이 간소화 된 요소 트리에서 Click 이벤트의 소스는 Button 요소 Button 중 하나 이며 클릭 한 것은 이벤트를 처리할 수 있는 첫 번째 요소입니다.In this simplified element tree, the source of a Click event is one of the Button elements, and whichever Button was clicked is the first element that has the opportunity to handle the event. 그러나에 연결 Button 된 처리기가 이벤트에 대해 작동 하지 않는 경우이 이벤트는 요소 StackPanel트리의 Button 부모 ()로 위쪽으로 버블링 됩니다.But if no handler attached to the Button acts on the event, then the event will bubble upwards to the Button parent in the element tree, which is the StackPanel. 잠재적으로 이벤트는로 Border버블링 된 다음 요소 트리의 페이지 루트 (표시 되지 않음)로 표시 됩니다.Potentially, the event bubbles to Border, and then beyond to the page root of the element tree (not shown).

즉,이 Click 이벤트에 대 한 이벤트 경로는 다음과 같습니다.In other words, the event route for this Click event is:


라우트된 이벤트에 대한 최상위 시나리오Top-level Scenarios for Routed Events

다음은 라우트된 이벤트 개념에 대해 동기를 받은 시나리오와 일반적인 CLR 이벤트가 이러한 시나리오에 적합 하지 않은 이유에 대 한 간략 한 요약입니다.The following is a brief summary of the scenarios that motivated the routed event concept, and why a typical CLR event was not adequate for these scenarios:

컨트롤 컴퍼지션 및 캡슐화: 의 다양 한 WPFWPF 컨트롤에는 풍부한 콘텐츠 모델이 있습니다.Control composition and encapsulation: Various controls in WPFWPF have a rich content model. 예를 들어, 단추의 시각적 트리를 효과적으로 확장 Button하는의 내에 이미지를 놓을 수 있습니다.For example, you can place an image inside of a Button, which effectively extends the visual tree of the button. 그러나 추가 된 이미지는 사용자가 기술적으로 이미지의 일부인 픽셀을 클릭 하더라도 단추가 해당 콘텐츠의에 응답 Click 하 게 하는 적중 테스트 동작을 중단 하면 안 됩니다.However, the added image must not break the hit-testing behavior that causes a button to respond to a Click of its content, even if the user clicks on pixels that are technically part of the image.

단일 처리기 첨부 파일 위치: Windows FormsWindows Forms에서는 여러 요소에서 발생할 수 있는 이벤트를 처리 하기 위해 동일한 처리기를 여러 번 연결 해야 합니다.Singular handler attachment points: In Windows FormsWindows Forms, you would have to attach the same handler multiple times to process events that could be raised from multiple elements. 라우트된 이벤트를 사용하면 이전 예제에서 살펴본 것처럼 해당 처리기를 한 번만 연결하고 처리기 논리를 사용하여 필요한 경우 이벤트가 발생한 위치를 확인할 수 있습니다.Routed events enable you to attach that handler only once, as was shown in the previous example, and use handler logic to determine where the event came from if necessary. 예를 들어 이것은 이전에 표시된 XAMLXAML에 대한 처리기일 수 있습니다.For instance, this might be the handler for the previously shown XAMLXAML:

private void CommonClickHandler(object sender, RoutedEventArgs e)
  FrameworkElement feSource = e.Source as FrameworkElement;
  switch (feSource.Name)
    case "YesButton":
      // do something here ...
    case "NoButton":
      // do something ...
    case "CancelButton":
      // do something ...
Private Sub CommonClickHandler(ByVal sender As Object, ByVal e As RoutedEventArgs)
  Dim feSource As FrameworkElement = TryCast(e.Source, FrameworkElement)
  Select Case feSource.Name
    Case "YesButton"
      ' do something here ...
    Case "NoButton"
      ' do something ...
    Case "CancelButton"
      ' do something ...
  End Select
End Sub

클래스 처리: 라우트된 이벤트는 클래스로 정의 된 정적 처리기를 허용 합니다.Class handling: Routed events permit a static handler that is defined by the class. 이 클래스 처리기는 연결된 인스턴스 처리기보다 먼저 이벤트를 처리할 수 있습니다.This class handler has the opportunity to handle an event before any attached instance handlers can.

리플렉션을 사용 하지 않고 이벤트 참조: 특정 코드 및 태그 기술에는 특정 이벤트를 식별 하는 방법이 필요 합니다.Referencing an event without reflection: Certain code and markup techniques require a way to identify a specific event. 라우트된 이벤트는 필드를 RoutedEvent 식별자로 만들며,이를 통해 정적 또는 런타임 리플렉션이 필요 하지 않은 강력한 이벤트 식별 기법을 사용할 수 있습니다.A routed event creates a RoutedEvent field as an identifier, which provides a robust event identification technique that does not require static or run-time reflection.

라우트된 이벤트를 구현하는 방법How Routed Events Are Implemented

라우트된 이벤트는 RoutedEvent 클래스의 인스턴스에서 지원 되 고 WPFWPF 이벤트 시스템에 등록 된 CLR 이벤트입니다.A routed event is a CLR event that is backed by an instance of the RoutedEvent class and registered with the WPFWPF event system. 등록에서 가져온 public static readonly 인스턴스는 일반적으로 라우트된 이벤트를 등록 하 고 "소유" 하는 클래스의 필드 멤버로 유지 됩니다. RoutedEventThe RoutedEvent instance obtained from registration is typically retained as a public static readonly field member of the class that registers and thus "owns" the routed event. 동일 하 게 명명 된 clr 이벤트 ("래퍼" 이벤트 라고도 함)에 대 한 연결은 CLR 이벤트에 대 한 addremove 구현을 재정의 하 여 수행 됩니다.The connection to the identically named CLR event (which is sometimes termed the "wrapper" event) is accomplished by overriding the add and remove implementations for the CLR event. 일반적으로 addremove는 해당 이벤트의 처리기를 추가 및 제거하기 위한 적절한 언어별 이벤트 구문을 사용하는 암시적 기본값으로 남아 있습니다.Ordinarily, the add and remove are left as an implicit default that uses the appropriate language-specific event syntax for adding and removing handlers of that event. 라우트된 이벤트 지원 및 연결 메커니즘은 개념적으로 종속성 속성이 DependencyProperty 클래스에서 지원 되 고 WPFWPF 속성 시스템에 등록 된 CLR 속성인 것과 비슷합니다.The routed event backing and connection mechanism is conceptually similar to how a dependency property is a CLR property that is backed by the DependencyProperty class and registered with the WPFWPF property system.

Tap 다음 예제에서는 RoutedEvent 식별자 필드 add 의 등록과 노출 및 Tap CLR 이벤트에 대 한 및 remove 구현을 포함 하 여 사용자 지정 라우트된 이벤트에 대 한 선언을 보여 줍니다.The following example shows the declaration for a custom Tap routed event, including the registration and exposure of the RoutedEvent identifier field and the add and remove implementations for the Tap CLR event.

public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
    "Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));

// Provide CLR accessors for the event
public event RoutedEventHandler Tap
        add { AddHandler(TapEvent, value); } 
        remove { RemoveHandler(TapEvent, value); }
Public Shared ReadOnly TapEvent As RoutedEvent = EventManager.RegisterRoutedEvent("Tap", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(MyButtonSimple))

' Provide CLR accessors for the event
Public Custom Event Tap As RoutedEventHandler
    AddHandler(ByVal value As RoutedEventHandler)
        Me.AddHandler(TapEvent, value)
    End AddHandler

    RemoveHandler(ByVal value As RoutedEventHandler)
        Me.RemoveHandler(TapEvent, value)
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)
    End RaiseEvent
End Event

라우트된 이벤트 처리기 및 XAMLRouted Event Handlers and XAML

XAMLXAML을 사용하여 이벤트 처리기를 추가하려면 이벤트 이름을 이벤트 수신기인 요소의 특성으로 선언합니다.To add a handler for an event using XAMLXAML, you declare the event name as an attribute on the element that is an event listener. 특성 값은 구현된 처리기 메서드의 이름으로, 코드 숨김 파일의 partial 클래스에 있어야 합니다.The value of the attribute is the name of your implemented handler method, which must exist in the partial class of the code-behind file.

<Button Click="b1SetColor">button</Button>

라우트된 이벤트 처리기를 추가 하기 위한 구문은라우트된이벤트처리기를추가하는것과같습니다.여기에는라우트된이벤트구현을포함하는clr이벤트래퍼에처리기를추가하는것이중요합니다.XAMLXAMLThe XAMLXAML syntax for adding standard CLR event handlers is the same for adding routed event handlers, because you are really adding handlers to the CLR event wrapper, which has a routed event implementation underneath. XAMLXAML의 이벤트 처리기 추가에 대한 자세한 내용은 XAML 개요(WPF)를 참조하세요.For more information about adding event handlers in XAMLXAML, see XAML Overview (WPF).

라우트 전략Routing Strategies

라우트된 이벤트는 다음 세 가지 라우트 전략 중 하나를 사용합니다.Routed events use one of three routing strategies:

  • 버블링 이벤트 원본에 대 한 이벤트 처리기가 호출 됩니다.Bubbling: Event handlers on the event source are invoked. 라우트된 이벤트는 요소 트리 루트에 도달할 때까지 다음 부모 요소로 라우트됩니다.The routed event then routes to successive parent elements until reaching the element tree root. 대부분의 라우트된 이벤트는 버블링 라우트 전략을 사용합니다.Most routed events use the bubbling routing strategy. 버블링 라우트된 이벤트는 일반적으로 개별 컨트롤 또는 기타 UI 요소에서 입력 또는 상태 변경을 보고하는 데 사용됩니다.Bubbling routed events are generally used to report input or state changes from distinct controls or other UI elements.

  • 계좌 소스 요소 자체에는 응답으로 처리기를 호출할 수 있는 기회가 제공 됩니다.Direct: Only the source element itself is given the opportunity to invoke handlers in response. 이 전략은 Windows FormsWindows Forms에서 이벤트에 사용하는 “라우트”와 비슷합니다.This is analogous to the "routing" that Windows FormsWindows Forms uses for events. 그러나 표준 CLR 이벤트와는 달리 직접 라우트된 이벤트는 클래스 처리를 지원 합니다. 클래스 처리는 이후 섹션에서 설명 하 고 및 EventSetter EventTrigger에서 사용할 수 있습니다.However, unlike a standard CLR event, direct routed events support class handling (class handling is explained in an upcoming section) and can be used by EventSetter and EventTrigger.

  • 터널링 처음에는 요소 트리 루트에 있는 이벤트 처리기가 호출 됩니다.Tunneling: Initially, event handlers at the element tree root are invoked. 그 다음에 라우트된 이벤트는 경로를 따라 있는 다음 자식 요소를 통해 경로를 이동하여 라우트된 이벤트 소스인 노드 요소(라우트된 이벤트를 발생시킨 요소)를 향합니다.The routed event then travels a route through successive child elements along the route, towards the node element that is the routed event source (the element that raised the routed event). 터널링 라우트된 이벤트는 보통 컨트롤 합치기의 일부로 사용 또는 처리되므로 복합 부분의 이벤트가 의도적으로 전체 컨트롤에 관련된 이벤트에 의해 억제되거나 대체될 수 있습니다.Tunneling routed events are often used or handled as part of the compositing for a control, such that events from composite parts can be deliberately suppressed or replaced by events that are specific to the complete control. WPFWPF에서 제공된 입력 이벤트는 터널링/버블링 쌍으로 구현됩니다.Input events provided in WPFWPF often come implemented as a tunneling/bubbling pair. 쌍에 사용되는 명명 규칙 때문에 터널링 이벤트를 미리 보기 이벤트라고도 합니다.Tunneling events are also sometimes referred to as Preview events, because of a naming convention that is used for the pairs.

라우트된 이벤트를 사용하는 이유는 무엇인가요?Why Use Routed Events?

애플리케이션 개발자가 항상 처리 중인 이벤트가 라우트된 이벤트로 구현되는지 알거나 주의할 필요는 없습니다.As an application developer, you do not always need to know or care that the event you are handling is implemented as a routed event. 라우트된 이벤트에는 특별한 동작이 있지만 이벤트가 발생한 요소에서 해당 이벤트를 처리할 경우 이 동작은 대체로 표시되지 않습니다.Routed events have special behavior, but that behavior is largely invisible if you are handling an event on the element where it is raised.

공통 루트에서 공통 처리기 정의, 자체 컨트롤 합치기 또는 자체 사용자 지정 컨트롤 클래스 정의와 같은 제안된 시나리오를 사용할 경우 라우트된 이벤트가 강력해집니다.Where routed events become powerful is if you use any of the suggested scenarios: defining common handlers at a common root, compositing your own control, or defining your own custom control class.

라우트된 이벤트 수신기와 라우트된 이벤트 소스는 계층 구조에서 공통 이벤트를 공유할 필요가 없습니다.Routed event listeners and routed event sources do not need to share a common event in their hierarchy. 모든 UIElement 또는ContentElement 는 모든 라우트된 이벤트에 대 한 이벤트 수신기 일 수 있습니다.Any UIElement or ContentElement can be an event listener for any routed event. 따라서 작업 API 집합 전체에서 사용할 수 있는 전체 라우트된 이벤트 집합을 응용 프로그램의 서로 다른 요소가 이벤트 정보를 교환할 수 있는 개념 "인터페이스"로 사용할 수 있습니다.Therefore, you can use the full set of routed events available throughout the working API set as a conceptual "interface" whereby disparate elements in the application can exchange event information. 라우트된 이벤트에 대한 이 “인터페이스” 개념은 특히 입력 이벤트에 적합합니다.This "interface" concept for routed events is particularly applicable for input events.

이벤트에 대한 이벤트 데이터는 경로의 각 요소에 대해 지속되기 때문에 라우트된 이벤트는 요소 트리를 통해 통신하는 데도 사용될 수 있습니다.Routed events can also be used to communicate through the element tree, because the event data for the event is perpetuated to each element in the route. 하나의 요소가 이벤트 데이터의 무엇인가를 변경할 수 있고 해당 변경은 경로의 다음 요소에 사용할 수 있습니다.One element could change something in the event data, and that change would be available to the next element in the route.

라우팅 측면 외에도 지정 WPFWPF 된 이벤트를 표준 CLR 이벤트 대신 라우트된 이벤트로 구현할 수 있는 두 가지 다른 이유가 있습니다.Other than the routing aspect, there are two other reasons that any given WPFWPF event might be implemented as a routed event instead of a standard CLR event. 자체 이벤트를 구현할 경우 다음 원칙을 고려할 수도 있습니다.If you are implementing your own events, you might also consider these principles:

  • EventSetter WPFWPF 와같은특정스타일지정및템플릿기능을통해참조되는이벤트를라우트된이벤트로EventTrigger 지정 해야 합니다.Certain WPFWPF styling and templating features such as EventSetter and EventTrigger require the referenced event to be a routed event. 이는 앞에서 언급한 이벤트 식별자 시나리오입니다.This is the event identifier scenario mentioned earlier.

  • 라우트된 이벤트는 등록된 인스턴스 처리기가 라우트된 이벤트에 액세스하기 전에 클래스가 라우트된 이벤트를 처리할 기회를 가지는 정적 메서드를 지정하는 데 사용될 수 있는 클래스 처리 메커니즘을 지원합니다.Routed events support a class handling mechanism whereby the class can specify static methods that have the opportunity to handle routed events before any registered instance handlers can access them. 이 메커니즘은 컨트롤 디자인에서 매우 유용합니다. 클래스는 이벤트가 인스턴스에서 처리되어 실수로 억제될 수 있는 이벤트 기반 클래스 동작을 강제 실행할 수 있기 때문입니다.This is very useful in control design, because your class can enforce event-driven class behaviors that cannot be accidentally suppressed by handling an event on an instance.

위 고려 사항은 각각 이 항목의 개별 섹션에서 설명합니다.Each of the above considerations is discussed in a separate section of this topic.

라우트된 이벤트에 대한 이벤트 처리기 추가 및 구현Adding and Implementing an Event Handler for a Routed Event

XAMLXAML에서 이벤트 처리기를 추가하려면 이벤트 이름을 요소에 특성으로 추가하고 특성 값을 다음 예제와 같이 적절한 대리자를 구현하는 이벤트 처리기의 이름으로 설정하면 됩니다.To add an event handler in XAMLXAML, you simply add the event name to an element as an attribute and set the attribute value as the name of the event handler that implements an appropriate delegate, as in the following example.

<Button Click="b1SetColor">button</Button>

b1SetColor이벤트를 Click 처리 하는 코드를 포함 하는 구현 된 처리기의 이름입니다.b1SetColor is the name of the implemented handler that contains the code that handles the Click event. b1SetColorRoutedEventHandler 이벤트Click 에 대 한 이벤트 처리기 대리자 인 대리자와 동일한 시그니처를 가져야 합니다.b1SetColor must have the same signature as the RoutedEventHandler delegate, which is the event handler delegate for the Click event. 모든 라우트된 이벤트 처리기 대리자의 첫 번째 매개 변수는 이벤트 처리기가 추가되는 요소를 지정하고 두 번째 매개 변수는 이벤트에 대한 데이터를 지정합니다.The first parameter of all routed event handler delegates specifies the element to which the event handler is added, and the second parameter specifies the data for the event.

void b1SetColor(object sender, RoutedEventArgs args)
  //logic to handle the Click event
Private Sub b1SetColor(ByVal sender As Object, ByVal args As RoutedEventArgs)
  'logic to handle the Click event
End Sub

RoutedEventHandler는 기본 라우트된 이벤트 처리기 대리자입니다.RoutedEventHandler is the basic routed event handler delegate. 특정 컨트롤 또는 시나리오에 특수화된 라우트된 이벤트의 경우 라우트된 이벤트 처리기에 사용할 대리자는 더 특수화되어 특수화된 이벤트 데이터를 전송할 수 있습니다.For routed events that are specialized for certain controls or scenarios, the delegates to use for the routed event handlers also might become more specialized, so that they can transmit specialized event data. 예를 들어 일반적인 입력 시나리오에서 DragEnter 라우트된 이벤트를 처리할 수 있습니다.For instance, in a common input scenario, you might handle a DragEnter routed event. 처리기에서 대리자를 DragEventHandler 구현 해야 합니다.Your handler should implement the DragEventHandler delegate. 가장 구체적인 대리자를 사용 하 여 처리기에서를 DragEventArgs 처리 하 고 끌기 작업의 클립보드 페이로드를 포함 하는 Data 속성을 읽을 수 있습니다.By using the most specific delegate, you can process the DragEventArgs in the handler and read the Data property, which contains the clipboard payload of the drag operation.

XAMLXAML을 사용하여 이벤트 처리기를 요소에 추가하는 방법의 전체 예제를 보려면 라우트된 이벤트 처리를 참조하세요.For a complete example of how to add an event handler to an element using XAMLXAML, see Handle a Routed Event.

코드로 만들어진 애플리케이션에 라우트된 이벤트에 대한 처리기를 추가하는 방법은 간단합니다.Adding a handler for a routed event in an application that is created in code is straightforward. 라우트된 이벤트 처리기는 항상 기존 백업에서 AddHandler add호출 하는 것과 동일한 메서드인 도우미 메서드를 통해 추가할 수 있습니다. 하지만 기존 WPFWPF 라우트된 이벤트에는 일반적으로 언어별 이벤트 구문(도우미 메서드보다 더 직관적인 구문)을 통해 라우트된 이벤트에 대한 처리기를 추가할 수 있는 addremove 논리의 지원 구현이 포함됩니다.Routed event handlers can always be added through a helper method AddHandler (which is the same method that the existing backing calls for add.) However, existing WPFWPF routed events generally have backing implementations of add and remove logic that allow the handlers for routed events to be added by a language-specific event syntax, which is more intuitive syntax than the helper method. 도우미 메서드 사용 예제는 다음과 같습니다.The following is an example usage of the helper method:

void MakeButton()
     Button b2 = new Button();
     b2.AddHandler(Button.ClickEvent, new RoutedEventHandler(Onb2Click));
 void Onb2Click(object sender, RoutedEventArgs e)
     //logic to handle the Click event     
Private Sub MakeButton()
     Dim b2 As New Button()
     b2.AddHandler(Button.ClickEvent, New RoutedEventHandler(AddressOf Onb2Click))
End Sub
 Private Sub Onb2Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
     'logic to handle the Click event     
 End Sub

다음 예에서는 C# 연산자 Visual Basic 구문을 보여 줍니다. 역참조를 처리 하기 때문에 연산자 구문이 약간 다릅니다.The next example shows the C# operator syntax (Visual Basic has slightly different operator syntax because of its handling of dereferencing):

void MakeButton2()
  Button b2 = new Button();
  b2.Click += new RoutedEventHandler(Onb2Click2);
void Onb2Click2(object sender, RoutedEventArgs e)
  //logic to handle the Click event     
Private Sub MakeButton2()
  Dim b2 As New Button()
  AddHandler b2.Click, AddressOf Onb2Click2
End Sub
Private Sub Onb2Click2(ByVal sender As Object, ByVal e As RoutedEventArgs)
  'logic to handle the Click event     
End Sub

이벤트 처리기를 코드에 추가하는 방법의 예제를 보려면 코드를 사용하여 이벤트 처리기 추가를 참조하세요.For an example of how to add an event handler in code, see Add an Event Handler Using Code.

Visual Basic를 사용 하는 경우 Handles 키워드를 사용 하 여 처리기를 처리기 선언의 일부로 추가할 수도 있습니다.If you are using Visual Basic, you can also use the Handles keyword to add handlers as part of the handler declarations. 자세한 내용은 Visual Basic 및 WPF 이벤트 처리를 참조하세요.For more information, see Visual Basic and WPF Event Handling.

Handled 개념The Concept of Handled

모든 라우트된 이벤트는 공용 이벤트 데이터 기본 클래스인을 RoutedEventArgs공유 합니다.All routed events share a common event data base class, RoutedEventArgs. RoutedEventArgs부울 값을 사용 하는 속성을정의합니다.HandledRoutedEventArgs defines the Handled property, which takes a Boolean value. Handled 속성의 목적은의 Handled 값을로 true설정 하 여 경로를 따라 라우트된 이벤트를 처리된 것으로 표시 하는 이벤트 처리기를 사용 하도록 설정 하는 것입니다.The purpose of the Handled property is to enable any event handler along the route to mark the routed event as handled, by setting the value of Handled to true. 경로를 따라 있는 한 요소에 있는 처리기에서 처리된 후 공유된 이벤트 데이터는 다시 경로를 따라 있는 각 수신기에 보고됩니다.After being processed by the handler at one element along the route, the shared event data is again reported to each listener along the route.

값은 경로 Handled 를 따라 추가로 이동할 때 라우트된 이벤트를 보고 하거나 처리 하는 방법에 영향을 줍니다.The value of Handled affects how a routed event is reported or processed as it travels further along the route. Handledtrue 라우트된 이벤트에 대 한 이벤트 데이터에 있으면 다른 요소에서 해당 라우트된 이벤트를 수신 하는 처리기는 일반적으로 해당 특정 이벤트 인스턴스에 대해 더 이상 호출 되지 않습니다.If Handled is true in the event data for a routed event, then handlers that listen for that routed event on other elements are generally no longer invoked for that particular event instance. XAMLXAML에서 연결된 처리기 및 += 또는 Handles와 같은 언어별 이벤트 처리기 연결 구문을 통해 추가된 처리기에도 이 내용이 적용됩니다.This is true both for handlers attached in XAMLXAML and for handlers added by language-specific event handler attachment syntaxes such as += or Handles. 대부분의 일반적인 처리기 시나리오에서을로 Handled true 설정 하 여 이벤트를 처리 된 것으로 표시 하면 터널링 경로 또는 버블링 경로에 대 한 라우팅을 "중지" 하 고 클래스 처리기에 의해 경로의 지점에서 처리 되는 모든 이벤트에 대해 "중지" 됩니다.For most common handler scenarios, marking an event as handled by setting Handled to true will "stop" routing for either a tunneling route or a bubbling route, and also for any event that is handled at a point in the route by a class handler.

그러나 수신기가 이벤트 데이터 Handled true 에 있는 라우트된 이벤트에 대 한 응답으로 처리기를 계속 실행할 수 있는 "handledEventsToo" 메커니즘이 있습니다.However, there is a "handledEventsToo" mechanism whereby listeners can still run handlers in response to routed events where Handled is true in the event data. 즉, 이벤트 데이터를 처리됨으로 표시해도 실제로 이벤트 경로는 중지되지 않습니다.In other words, the event route is not truly stopped by marking the event data as handled. 코드 또는에서 EventSetterhandledEventsToo 메커니즘도 사용할 수 있습니다.You can only use the handledEventsToo mechanism in code, or in an EventSetter:

HandledHandled 개념은 라우트된 이벤트에서 상태가 생성 하는 동작 외에도 응용 프로그램을 디자인 하 고 이벤트 처리기 코드를 작성 하는 방법에 영향을 줍니다.In addition to the behavior that Handled state produces in routed events, the concept of Handled has implications for how you should design your application and write the event handler code. 라우트된 이벤트에 Handled 의해 노출 되는 단순한 프로토콜로 이해할 수 있습니다.You can conceptualize Handled as being a simple protocol that is exposed by routed events. 이 프로토콜을 사용 하는 정확한 방법은 사용자에 게 적합 하지만의 Handled 값을 사용 하는 방법에 대 한 개념 디자인은 다음과 같습니다.Exactly how you use this protocol is up to you, but the conceptual design for how the value of Handled is intended to be used is as follows:

  • 라우트된 이벤트가 처리됨으로 표시되면 해당 경로를 따라 있는 다른 요소가 해당 라우트된 이벤트를 다시 처리할 필요가 없습니다.If a routed event is marked as handled, then it does not need to be handled again by other elements along that route.

  • 라우트된 이벤트가 처리 된 것으로 표시 되지 않은 경우 경로를 따라 이전에 있던 다른 수신기가 처리기를 등록 하지 않거나 등록 된 처리기가 이벤트 데이터를 조작 하 고로 Handled true설정 하지 않도록 선택 했습니다.If a routed event is not marked as handled, then other listeners that were earlier along the route have chosen either not to register a handler, or the handlers that were registered chose not to manipulate the event data and set Handled to true. 또는 현재 수신기가 경로의 첫 번째 지점일 수도 있습니다. 이제 현재 수신기의 처리기에는 세 가지 가능한 작업 과정이 있습니다.(Or, it is of course possible that the current listener is the first point in the route.) Handlers on the current listener now have three possible courses of action:

    • 아무 작업도 수행하지 않습니다. 이벤트는 처리되지 않고 다음 수신기로 라우트됩니다.Take no action at all; the event remains unhandled, and the event routes to the next listener.

    • 이벤트에 대한 응답으로 코드를 실행하지만 수행된 작업이 이벤트를 처리됨으로 표시하도록 보장할 만큼 충분히 효과적인지에 대한 결정을 내립니다.Execute code in response to the event, but make the determination that the action taken was not substantial enough to warrant marking the event as handled. 이벤트는 다음 수신기로 라우트됩니다.The event routes to the next listener.

    • 이벤트에 대한 응답으로 코드를 실행합니다.Execute code in response to the event. 처리기에 전달된 이벤트 데이터에서 이벤트를 처리됨으로 표시합니다. 이는 수행된 작업이 처리됨으로 표시하도록 보장할 만큼 충분히 효과적이라고 생각되기 때문입니다.Mark the event as handled in the event data passed to the handler, because the action taken was deemed substantial enough to warrant marking as handled. 이벤트는 계속 해 서 다음 수신기로 라우트 하지만 이벤트 Handled 데이터에서를 사용 = true 하 여 수신기 handledEventsToo 만 추가 처리기를 호출할 수 있습니다.The event still routes to the next listener, but with Handled=true in its event data, so only handledEventsToo listeners have the opportunity to invoke further handlers.

이 개념 디자인은 앞에서 언급 한 라우팅 동작에 의해 강화 됩니다. 경로를 따라 이전 처리기가 이미 설정 Handled된경우에도호출되는라우트된이벤트에대한처리기를연결하는것이더어렵거나(코드또는스타일에서도가능하지만) totrue.This conceptual design is reinforced by the routing behavior mentioned earlier: it is more difficult (although still possible in code or styles) to attach handlers for routed events that are invoked even if a previous handler along the route has already set Handled to true.

Handled대 한 자세한 내용, 라우트된 이벤트의 클래스 처리 및 라우트된 이벤트를로 Handled표시 하는 것이 적절 한 경우에 대 한 권장 사항은 라우트된 이벤트를 처리 된 것으로 표시 및 클래스 처리를 참조 하세요.For more information about Handled, class handling of routed events, and recommendations about when it is appropriate to mark a routed event as Handled, see Marking Routed Events as Handled, and Class Handling.

애플리케이션에서는 일반적으로 버블링 라우트된 이벤트를 발생시킨 개체에서 이 이벤트를 처리하며 이벤트의 라우트 특징은 전혀 관련이 없습니다.In applications, it is quite common to just handle a bubbling routed event on the object that raised it, and not be concerned with the event's routing characteristics at all. 하지만 요소 트리에서 더 위쪽에 있는 요소에 같은 라우트된 이벤트에 대한 연결된 처리기가 있는 경우 예기치 않은 부작용을 방지하기 위해 이벤트 데이터에서는 라우트된 이벤트를 처리됨으로 표시하는 것이 좋습니다.However, it is still a good practice to mark the routed event as handled in the event data, to prevent unanticipated side effects just in case an element that is further up the element tree also has a handler attached for that same routed event.

클래스 처리기Class Handlers

에서 DependencyObject파생 되는 클래스를 정의 하는 경우 클래스의 선언 되거나 상속 된 이벤트 멤버인 라우트된 이벤트에 대 한 클래스 처리기를 정의 하 고 연결할 수도 있습니다.If you are defining a class that derives in some way from DependencyObject, you can also define and attach a class handler for a routed event that is a declared or inherited event member of your class. 라우트된 이벤트가 경로의 요소 인스턴스에 도달할 때마다 클래스 처리기는 해당 클래스의 인스턴스에 연결된 인스턴스 수신기 처리기보다 먼저 호출됩니다.Class handlers are invoked before any instance listener handlers that are attached to an instance of that class, whenever a routed event reaches an element instance in its route.

일부 WPFWPF 컨트롤에는 특정 라우트된 이벤트에 대한 고유 클래스 처리 기능이 있습니다.Some WPFWPF controls have inherent class handling for certain routed events. 이 기능을 사용하면 표면적으로는 라우트된 이벤트가 발생하지 않은 것처럼 보이지만 실제로는 클래스가 처리되는 것이고 특정 기술을 사용하면 라우트된 이벤트가 인스턴스 처리기에서 처리될 수 있습니다.This might give the outward appearance that the routed event is not ever raised, but in reality it is being class handled, and the routed event can potentially still be handled by your instance handlers if you use certain techniques. 또한 많은 기본 클래스 및 컨트롤이 클래스 처리 동작을 재정의하는 데 사용될 수 있는 가상 메서드를 표시합니다.Also, many base classes and controls expose virtual methods that can be used to override class handling behavior. 원하지 않는 클래스 처리를 해결하는 방법 및 사용자 지정 클래스에서 자체 클래스 처리를 정의하는 방법에 대한 자세한 내용은 라우트된 이벤트를 처리된 것으로 표시 및 클래스 처리를 참조하세요.For more information both on how to work around undesired class handling and on defining your own class handling in a custom class, see Marking Routed Events as Handled, and Class Handling.

WPF의 연결된 이벤트Attached Events in WPF

XAMLXAML 언어는 연결된 이벤트라는 특수 이벤트 형식을 정의합니다.The XAMLXAML language also defines a special type of event called an attached event. 연결된 이벤트를 사용하여 특정 이벤트에 대한 처리기를 임의 요소에 추가할 수 있습니다.An attached event enables you to add a handler for a particular event to an arbitrary element. 이벤트를 처리하는 요소는 연결된 이벤트를 정의하거나 상속할 필요가 없고 이벤트를 발생시키는 개체 및 인스턴스를 처리하는 대상은 모두 해당 이벤트를 클래스 멤버로 정의하거나 소유하면 안 됩니다.The element handling the event need not define or inherit the attached event, and neither the object potentially raising the event nor the destination handling instance must define or otherwise "own" that event as a class member.

WPFWPF 입력 시스템은 연결된 이벤트를 광범위하게 사용합니다.The WPFWPF input system uses attached events extensively. 하지만 이러한 연결된 이벤트는 거의 모두 기본 요소를 통해 전달됩니다.However, nearly all of these attached events are forwarded through base elements. 그 다음에 입력 이벤트는 기본 요소 클래스의 멤버인 해당하는 연결되지 않은 라우트된 이벤트로 표시됩니다.The input events then appear as equivalent non-attached routed events that are members of the base element class. 예를 들어 또는 코드에서 Mouse.MouseDown MouseDown UIElement UIElement 연결XAMLXAML 된 이벤트 구문을 처리 하는 대신를 사용 하 여 지정 된에서 기본 연결 된 이벤트를 보다 쉽게 처리할 수 있습니다.For instance, the underlying attached event Mouse.MouseDown can more easily be handled on any given UIElement by using MouseDown on that UIElement rather than dealing with attached event syntax either in XAMLXAML or code.

WPFWPF의 연결된 이벤트에 대한 자세한 내용은 연결된 이벤트 개요를 참조하세요.For more information about attached events in WPFWPF, see Attached Events Overview.

XAML의 정규화된 이벤트 이름Qualified Event Names in XAML

typename.eventname 연결된 이벤트 구문과 비슷하지만 엄격히 말하면 연결된 이벤트 사용이 아닌 또 다른 구문 사용은 자식 요소에서 발생한 라우트된 이벤트에 대한 처리기를 연결하는 경우입니다.Another syntax usage that resembles typename.eventname attached event syntax but is not strictly speaking an attached event usage is when you attach handlers for routed events that are raised by child elements. 공통 부모에 관련 라우트된 이벤트가 멤버로 포함되지 않더라도 처리기를 공통 부모에 연결하면 이벤트 라우트를 이용할 수 있습니다.You attach the handlers to a common parent, to take advantage of event routing, even though the common parent might not have the relevant routed event as a member. 이 예제를 다시 살펴보세요.Consider this example again:

<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
  <StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler">
    <Button Name="YesButton" Width="Auto" >Yes</Button>
    <Button Name="NoButton" Width="Auto" >No</Button>
    <Button Name="CancelButton" Width="Auto" >Cancel</Button>

여기서 처리기가 추가 StackPanel되는 부모 요소 수신기는입니다.Here, the parent element listener where the handler is added is a StackPanel. 그러나 선언 되었으며 Button 클래스에서 발생 하는 라우트된 이벤트에 대 한 처리기를 추가 하는 것입니다 (ButtonBase 실제로는 이지만 상속을 Button 통해 사용 가능).However, it is adding a handler for a routed event that was declared and will be raised by the Button class (ButtonBase actually, but available to Button through inheritance). Button이벤트를 "소유" 하지만 라우트된 이벤트 시스템은 라우트된 모든 이벤트에 대 한 처리기를 CLR (공용 언어 UIElement 런타임 ContentElement ) 이벤트에 대 한 수신기를 연결할 수 있는 모든 또는 인스턴스 수신기에 연결할 수 있습니다.Button "owns" the event, but the routed event system permits handlers for any routed event to be attached to any UIElement or ContentElement instance listener that could otherwise attach listeners for a common language runtime (CLR) event. 일반적으로 이러한 정규화된 이벤트 특성 이름에 대한 기본 xmlns 네임스페이스는 기본 WPFWPF xmlns 네임스페이스이지만 사용자 지정 라우트된 이벤트에 대한 접두사가 추가된 네임스페이스를 지정할 수도 있습니다.The default xmlns namespace for these qualified event attribute names is typically the default WPFWPF xmlns namespace, but you can also specify prefixed namespaces for custom routed events. xmlns에 대한 자세한 내용은 WPF XAML을 위한 XAML 네임스페이스 및 네임스페이스 매핑을 참조하세요.For more information about xmlns, see XAML Namespaces and Namespace Mapping for WPF XAML.

WPF 입력 이벤트WPF Input Events

WPFWPF 플랫폼 내에서 라우트된 이벤트가 자주 사용되는 한 가지 응용 프로그램은 입력 이벤트와 관련됩니다.One frequent application of routed events within the WPFWPF platform is for input events. WPFWPF에서 터널링 라우트된 이벤트에는 규칙에 따라 "Preview"라는 단어가 접두사로 추가됩니다.In WPFWPF, tunneling routed events names are prefixed with the word "Preview" by convention. 입력 이벤트는 보통 쌍으로 제공되고, 쌍 중 하나는 버블링 이벤트가 되고 다른 하나는 터널링 이벤트가 됩니다.Input events often come in pairs, with one being the bubbling event and the other being the tunneling event. KeyDown 를 들어 이벤트 PreviewKeyDown 와 이벤트는 동일한 서명을 가지 며, 이전에는 버블링 입력 이벤트로, 후자는 터널링 입력 이벤트입니다.For example, the KeyDown event and the PreviewKeyDown event have the same signature, with the former being the bubbling input event and the latter being the tunneling input event. 입력 이벤트에 버블링 버전만 포함되거나 직접 라우트된 버전만 포함되는 경우도 있습니다.Occasionally, input events only have a bubbling version, or perhaps only a direct routed version. 문서의 라우트된 이벤트 항목에서는 라우트된 이벤트가 있는 경우 대체 라우트 전략을 통해 비슷한 라우트된 이벤트를 상호 참조하고 관리되는 참조 페이지의 섹션에서는 각 라우트된 이벤트의 라우트 전략을 설명합니다.In the documentation, routed event topics cross-reference similar routed events with alternative routing strategies if such routed events exist, and sections in the managed reference pages clarify the routing strategy of each routed event.

쌍으로 제공되는 WPFWPF 입력 이벤트는 마우스 단추 누르기와 같은 입력의 단일 사용자 작업이 해당 쌍의 라우트된 이벤트를 둘 다 순차적으로 발생시키도록 구현됩니다.WPFWPF input events that come in pairs are implemented so that a single user action from input, such as a mouse button press, will raise both routed events of the pair in sequence. 먼저 터널링 이벤트가 발생하고 경로를 이동합니다.First, the tunneling event is raised and travels its route. 그 다음에 버블링 이벤트가 발생하고 경로를 이동합니다.Then the bubbling event is raised and travels its route. 버블링 이벤트를 발생 시키는 구현 클래스의 RaiseEvent 메서드 호출은 터널링 이벤트에서 이벤트 데이터를 수신 하 고 새 발생 이벤트에서 다시 사용할 수 있기 때문에 두 이벤트는 동일한 이벤트 데이터 인스턴스를 그대로 공유 합니다.The two events literally share the same event data instance, because the RaiseEvent method call in the implementing class that raises the bubbling event listens for the event data from the tunneling event and reuses it in the new raised event. 터널링 이벤트에 대한 처리기가 있는 수신기는 우선적으로 라우트된 이벤트를 처리됨으로 표시할 수 있습니다(클래스 처리기 우선, 그 다음에 인스턴스 처리기).Listeners with handlers for the tunneling event have the first opportunity to mark the routed event handled (class handlers first, then instance handlers). 터널링 경로에 따라 있는 요소가 라우트된 이벤트를 처리됨으로 표시한 경우 버블링 이벤트에 대한 이미 처리된 이벤트 데이터가 전송되고 해당하는 버블링 입력 이벤트에 대한 일반 연결된 처리기는 호출되지 않습니다.If an element along the tunneling route marked the routed event as handled, the already-handled event data is sent on for the bubbling event, and typical handlers attached for the equivalent bubbling input events will not be invoked. 표면적으로는 처리된 버블링 이벤트가 발생하지 않은 경우처럼 보입니다.To outward appearances it will be as if the handled bubbling event has not even been raised. 이 처리 동작은 컨트롤 합치기에 유용합니다. 이 경우 모든 적중 테스트 기반 입력 이벤트나 포커스 기반 입력 이벤트를 복합 부분이 아닌 최종 컨트롤이 보고하도록 할 수 있습니다.This handling behavior is useful for control compositing, where you might want all hit-test based input events or focus-based input events to be reported by your final control, rather than its composite parts. 최종 컨트롤 요소는 합치기에서 루트에 더 근접하므로 터널링 이벤트를 먼저 클래스에서 처리하고 라우트된 이벤트를 컨트롤에 대한 관련성이 더 높은 이벤트(컨트롤 클래스를 지원하는 코드의 일부)로 “대체”할 수 있습니다.The final control element is closer to the root in the compositing, and therefore has the opportunity to class handle the tunneling event first and perhaps to "replace" that routed event with a more control-specific event, as part of the code that backs the control class.

입력 이벤트 처리가 적용되는 방식에 대한 그림으로 다음 입력 이벤트 예제를 살펴보겠습니다.As an illustration of how input event processing works, consider the following input event example. 다음 트리 그림 leaf element #2 에서는 PreviewMouseDownMouseDown 이벤트의 소스입니다.In the following tree illustration, leaf element #2 is the source of both a PreviewMouseDown and then a MouseDown event:

이벤트 라우팅 다이어그램

이벤트 처리 순서는 다음과 같습니다.The order of event processing is as follows:

  1. 루트 요소의 PreviewMouseDown(터널링).PreviewMouseDown (tunnel) on root element.

  2. 중간 요소 #1의 PreviewMouseDown(터널링).PreviewMouseDown (tunnel) on intermediate element #1.

  3. 소스 요소 #2의 PreviewMouseDown(터널링).PreviewMouseDown (tunnel) on source element #2.

  4. 소스 요소 #2의 MouseDown(버블링).MouseDown (bubble) on source element #2.

  5. 중간 요소 #1의 MouseDown(버블링).MouseDown (bubble) on intermediate element #1.

  6. 루트 요소의 MouseDown(버블링).MouseDown (bubble) on root element.

라우트된 이벤트 처리기 대리자는 두 개체인, 이벤트를 발생시킨 개체 및 처리기가 호출된 개체에 대한 참조를 제공합니다.A routed event handler delegate provides references to two objects: the object that raised the event and the object where the handler was invoked. 처리기가 호출된 개체는 sender 매개 변수를 통해 보고된 개체입니다.The object where the handler was invoked is the object reported by the sender parameter. 이벤트가 처음 발생 한 개체는 이벤트 데이터의 Source 속성에 의해 보고 됩니다.The object where the event was first raised is reported by the Source property in the event data. 라우트된 이벤트는 같은 개체에서 계속 발생 하 고 처리할 수 있습니다 .이 경우 senderSource 는 동일 합니다 (이벤트 처리 예제 목록에서 3 단계 및 4 단계를 사용 하는 경우).A routed event can still be raised and handled by the same object, in which case sender and Source are identical (this is the case with Steps 3 and 4 in the event processing example list).

터널링 및 버블링으로 인해 부모 요소는 Source 이 자식 요소 중 하나인 입력 이벤트를 수신 합니다.Because of tunneling and bubbling, parent elements receive input events where the Source is one of their child elements. 원본 요소를 파악 하는 것이 중요 한 경우 Source 속성에 액세스 하 여 원본 요소를 식별할 수 있습니다.When it is important to know what the source element is, you can identify the source element by accessing the Source property.

일반적으로 입력 이벤트가 표시 Handled되 면 추가 처리기가 호출 되지 않습니다.Usually, once the input event is marked Handled, further handlers are not invoked. 보통은 입력 이벤트의 의미에 대한 애플리케이션별 논리 처리를 해결하는 처리기가 호출된 후 바로 입력 이벤트를 처리됨으로 표시해야 합니다.Typically, you should mark input events as handled as soon as a handler is invoked that addresses your application-specific logical handling of the meaning of the input event.

상태에 대 한 Handled 이 일반적인 문의 예외는 이벤트 데이터의 상태를 의도적으로 무시 Handled 하도록 등록 된 입력 이벤트 처리기가 경로를 따라 계속 호출 된다는 것입니다.The exception to this general statement about Handled state is that input event handlers that are registered to deliberately ignore Handled state of the event data would still be invoked along either route. 자세한 내용은 미리 보기 이벤트 또는 라우트된 이벤트를 처리된 것으로 표시 및 클래스 처리를 참조하세요.For more information, see Preview Events or Marking Routed Events as Handled, and Class Handling.

터널링 이벤트와 버블링 이벤트 간에 공유된 이벤트 데이터 모델과 터널링 이벤트 다음에 버블링 이벤트가 발생하는 순차적 발생은 일반적으로 모든 라우트된 이벤트에 적용되는 개념이 아닙니다.The shared event data model between tunneling and bubbling events, and the sequential raising of first tunneling then bubbling events, is not a concept that is generally true for all routed events. 이 동작은 특별히 WPFWPF 입력 디바이스가 입력 이벤트 쌍을 발생시키고 연결하도록 선택하는 방법을 통해 구현됩니다.That behavior is specifically implemented by how WPFWPF input devices choose to raise and connect the input event pairs. 자체 입력 이벤트를 구현하는 것은 고급 시나리오이지만 자체 입력 이벤트에 대해 해당 모델을 따르도록 선택할 수도 있습니다.Implementing your own input events is an advanced scenario, but you might choose to follow that model for your own input events also.

특정 클래스는 대개 특정 사용자 기반 입력 이벤트가 해당 컨트롤 내에서 가지는 의미를 다시 정의하고 새 이벤트를 발생시키기 위해 특정 입력 이벤트를 클래스에서 처리하도록 선택합니다.Certain classes choose to class-handle certain input events, usually with the intent of redefining what a particular user-driven input event means within that control and raising a new event. 자세한 내용은 라우트된 이벤트를 처리된 것으로 표시 및 클래스 처리를 참조하세요.For more information, see Marking Routed Events as Handled, and Class Handling.

입력 및 입력과 이벤트가 일반적인 애플리케이션 시나리오에서 상호 작용하는 방식에 대한 자세한 내용은 입력 개요를 참조하세요.For more information on input and how input and events interact in typical application scenarios, see Input Overview.

EventSetter 및 EventTriggerEventSetters and EventTriggers

스타일에서를 EventSetter사용 하 여 태그에 미리 선언 XAMLXAML 된 이벤트 처리 구문을 포함할 수 있습니다.In styles, you can include some pre-declared XAMLXAML event handling syntax in the markup by using an EventSetter. 스타일이 적용되면 참조된 처리기가 스타일 지정된 인스턴스에 추가됩니다.When the style is applied, the referenced handler is added to the styled instance. 라우트된 이벤트에 대해서 EventSetter 만를 선언할 수 있습니다.You can declare an EventSetter only for a routed event. 다음은 예제입니다.The following is an example. 여기서 참조되는 b1SetColor 메서드는 코드 숨김 파일에 있습니다.Note that the b1SetColor method referenced here is in a code-behind file.

    <Style TargetType="{x:Type Button}">
      <EventSetter Event="Click" Handler="b1SetColor"/>
  <Button>Click me</Button>
  <Button Name="ThisButton" Click="HandleThis">
    Raise event, handle it, use handled=true handler to get it anyway.

여기에서 얻을 수 있는 이점은 응용 프로그램의 모든 단추에 적용 될 수 있는 다양 한 정보를 스타일에 포함할 수 있고 해당 스타일의 일부가 되도록 하면 EventSetter 태그 수준 에서도 코드 재사용을 촉진 하는 것입니다.The advantage gained here is that the style is likely to contain a great deal of other information that could apply to any button in your application, and having the EventSetter be part of that style promotes code reuse even at the markup level. EventSetter 또한 처리기에 대 한 메서드 이름이 일반 응용 프로그램 및 페이지 태그에서 한 단계 더 멀리 떨어져 있습니다.Also, an EventSetter abstracts method names for handlers one step further away from the general application and page markup.

WPFWPFEventTrigger라우트된 이벤트와 애니메이션 기능을 결합 하는 또 다른 특수화 된 구문은입니다.Another specialized syntax that combines the routed event and animation features of WPFWPF is an EventTrigger. EventSetter마찬가지로 라우트된 이벤트만 EventTrigger에 사용 될 수 있습니다.As with EventSetter, only routed events may be used for an EventTrigger. 일반적으로는 EventTrigger 스타일의 일부로 선언 되지만는 EventTrigger 페이지 수준 Triggers 요소에 대해 컬렉션의 일부로 선언 하거나에서 ControlTemplate선언할 수도 있습니다.Typically, an EventTrigger is declared as part of a style, but an EventTrigger can also be declared on page-level elements as part of the Triggers collection, or in a ControlTemplate. 를 사용 하면 라우트된 이벤트가 해당 Storyboard 이벤트 EventTrigger 에 대해를 선언 하는 해당 경로에 있는 요소에 도달할 때마다 실행 되는를 지정할 수 있습니다. EventTriggerAn EventTrigger enables you to specify a Storyboard that runs whenever a routed event reaches an element in its route that declares an EventTrigger for that event. 는 이벤트를 처리 EventTrigger 하 고 기존 storyboard를 시작 하도록 하는 것에 비해는 스토리 보드 및 EventTrigger 해당 런타임 동작에 대 한 보다 효율적인 제어를 제공 한다는 점입니다.The advantage of an EventTrigger over just handling the event and causing it to start an existing storyboard is that an EventTrigger provides better control over the storyboard and its run-time behavior. 자세한 내용은 Storyboard를 시작한 후 이벤트 트리거를 사용하여 제어를 참조하세요.For more information, see Use Event Triggers to Control a Storyboard After It Starts.

라우트된 이벤트에 대한 추가 정보More About Routed Events

이 항목에서는 기본 개념을 설명하고 다양한 기본 요소 및 컨트롤에 이미 있는 라우트된 이벤트에 응답하는 방법 및 시점에 대한 지침을 제공하는 관점에서 주로 라우트된 이벤트를 살펴봅니다.This topic mainly discusses routed events from the perspective of describing the basic concepts and offering guidance on how and when to respond to the routed events that are already present in the various base elements and controls. 하지만 특수화된 이벤트 데이터 클래스 및 대리자와 같은 모든 필요한 지원과 함께 사용자 지정 클래스에서 자체 라우트된 이벤트를 만들 수 있습니다.However, you can create your own routed event on your custom class along with all the necessary support, such as specialized event data classes and delegates. 라우트된 이벤트 소유자는 모든 클래스가 될 수 있지만, 라우트된 이벤트는에 의해 발생 하 고 UIElement 또는 ContentElement 파생 클래스에 의해 처리 되어야 유용 합니다.The routed event owner can be any class, but routed events must be raised by and handled by UIElement or ContentElement derived classes in order to be useful. 사용자 지정 이벤트에 대한 자세한 내용은 사용자 지정 라우트된 이벤트 만들기를 참조하세요.For more information about custom events, see Create a Custom Routed Event.

참고자료See also