연결된 이벤트 개요Attached Events Overview

확장 가능한 응용 프로그램 태그 언어(XAML)는 연결된 이벤트라는언어 구성 요소 및 이벤트 유형을 정의합니다.Extensible Application Markup Language (XAML) defines a language component and type of event called an attached event. 연결된 이벤트의 개념을 사용하면 실제로 정의하거나 이벤트를 상속하는 요소가 아닌 임의의 요소에 특정 이벤트의 핸들러를 추가할 수 있습니다.The concept of an attached event enables you to add a handler for a particular event to an arbitrary element rather than to an element that actually defines or inherits the event. 이 경우 이벤트를 잠재적으로 발생시키는 개체나 인스턴스를 처리하는 대상이 정의하지 않으며 또는 그렇지 않으면 이벤트를 "소유"합니다.In this case, neither the object potentially raising the event nor the destination handling instance defines or otherwise "owns" the event.

전제 조건Prerequisites

이 항목에서는 라우트된 이벤트 개요XAML 개요(WPF)를 읽었다고 가정합니다.This topic assumes that you have read Routed Events Overview and XAML Overview (WPF).

연결된 이벤트 구문Attached Event Syntax

연결된 이벤트에는 XAML 구문과 연결된 이벤트 사용을 지원하기 위해 백업 코드에서 사용해야 하는 코딩 패턴이 있습니다.Attached events have a XAML syntax and a coding pattern that must be used by the backing code in order to support the attached event usage.

XAML 구문에서 연결된 이벤트는 이벤트 이름뿐만 아니라 자체 형식과 이벤트 이름으로 지정되며 dot(.)으로 구분됩니다.In XAML syntax, the attached event is specified not just by its event name, but by its owning type plus the event name, separated by a dot (.). 이벤트 이름이 소유 형식의 이름으로 정규화되기 때문에, 연결된 이벤트 구문을 모든 연결된 이벤트를 인스턴스화할 수 있는 모든 요소에 연결할 수 있습니다.Because the event name is qualified with the name of its owning type, the attached event syntax allows any attached event to be attached to any element that can be instantiated.

예를 들어 다음은 사용자 지정 NeedsCleaning 연결 이벤트에 대한 처리기를 연결하기 위한 XAML 구문입니다.For example, the following is the XAML syntax for attaching a handler for a custom NeedsCleaning attached event:

<aqua:Aquarium Name="theAquarium" Height="600" Width="800" aqua:AquariumFilter.NeedsCleaning="WashMe"/>

aqua: 접두사. 연결된 이벤트가 사용자 지정 맵핑된 xmlns에서 오는 사용자 지정 이벤트이기 때문에 이 경우에 접두사가 필요합니다.Note the aqua: prefix; the prefix is necessary in this case because the attached event is a custom event that comes from a custom mapped xmlns.

WPF가 연결된 이벤트를 구현하는 방법How WPF Implements Attached Events

WPF에서 연결된 이벤트는 RoutedEvent 필드에 의해 백업되며 발생 후 트리를 통해 라우팅됩니다.In WPF, attached events are backed by a RoutedEvent field and are routed through the tree after they are raised. 일반적으로 연결된 이벤트(이벤트를 발생하는 개체)의 소스는 시스템이나 서비스 소스이며, 이벤트를 발생하는 코드를 실행하는 개체는 직접적인 요소 트리 파트가 아닙니다.Typically, the source of the attached event (the object that raises the event) is a system or service source, and the object that runs the code that raises the event is therefore not a direct part of the element tree.

연결된 이벤트에 대한 시나리오Scenarios for Attached Events

WPF에서 연결된 이벤트는 정적 Mouse 클래스 또는 Validation 클래스에서 활성화된 이벤트와 같이 서비스 수준 추상화가 있는 특정 기능 영역에 있습니다.In WPF, attached events are present in certain feature areas where there is service-level abstraction, such as for the events enabled by the static Mouse class or the Validation class. 서비스와 상호 작용하거나 사용하는 클래스는 연결된 이벤트 구문에서 이벤트를 사용하거나, 클래스가 서비스의 기능을 통합하는 방법의 일부인 라우트된 이벤트로 연결된 이벤트를 나타내도록 선택할 수 있습니다.Classes that interact with or use the service can either use the event in the attached event syntax, or they can choose to surface the attached event as a routed event that is part of how the class integrates the capabilities of the service.

WPF는 여러 연결된 이벤트를 정의하지만 연결된 이벤트를 직접 사용하거나 처리하는 시나리오는 매우 제한적입니다.Although WPF defines a number of attached events, the scenarios where you will either use or handle the attached event directly are very limited. 일반적으로 연결된 이벤트는 아키텍처 목적으로 사용되지만 연결되지 않은 이벤트(CLR 이벤트 "래퍼"로 백업)로 전달됩니다.Generally, the attached event serves an architecture purpose, but is then forwarded to a non-attached (backed with a CLR event "wrapper") routed event.

예를 들어 XAML Mouse.MouseDown 또는 코드에서 연결된 UIElement 이벤트 MouseDown 구문을 UIElement 처리하는 대신 기본 연결 이벤트를 사용하여 지정된 이벤트를 보다 쉽게 처리할 수 있습니다.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 XAML or code. 입력 디바이스의 향후 확장을 허용하므로 연결된 이벤트는 아키텍처의 용도로 사용됩니다.The attached event serves a purpose in the architecture because it allows for future expansion of input devices. 가상 의 장치는 마우스 입력을 Mouse.MouseDown 시뮬레이션하기 위해 상승해야하며, Mouse 그렇게하기 위해 파생 할 필요가 없습니다.The hypothetical device would only need to raise Mouse.MouseDown in order to simulate mouse input, and would not need to derive from Mouse to do so. 그러나 이 시나리오에는 이벤트의 코드 처리가 포함되며 연결된 이벤트의 XAML 처리는 이 시나리오와 관련이 없습니다.However, this scenario involves code handling of the events, and XAML handling of the attached event is not relevant to this scenario.

WPF에서 연결된 이벤트 처리Handling an Attached Event in WPF

연결된 이벤트를 처리하기 위한 프로세스 및 작성할 처리기 코드는 기본적으로 라우트된 이벤트의 경우와 동일합니다.The process for handling an attached event, and the handler code that you will write, is basically the same as for a routed event.

일반적으로 WPF 연결 된 이벤트는 WPF 라우트된 이벤트와 크게 다르지 않습니다.In general, a WPF attached event is not very different from a WPF routed event. 차이점은 이벤트의 소스와 클래스가 멤버로 노출되는 방식(XAML 처리기 구문에도 영향을 줍니다)입니다.The differences are how the event is sourced and how it is exposed by a class as a member (which also affects the XAML handler syntax).

그러나 앞에서 설명한 것처럼 기존 WPF 연결 이벤트는 특히 WPF에서 처리하기 위한 것이 아닙니다.However, as noted earlier, the existing WPF attached events are not particularly intended for handling in WPF. 이벤트의 목적은 합성 이벤트가 작성 시 부모 요소에 상태를 보고할 수 있게 하는 것으로, 이 경우 이벤트는 일반적으로 코드에서 발생하며 관련 부모 클래스에서 처리하는 클래스에도 사용됩니다.More often, the purpose of the event is to enable a composited element to report a state to a parent element in compositing, in which case the event is usually raised in code and also relies on class handling in the relevant parent class. 예를 들어, a Selector 내의 항목은 Selected 연결된 이벤트를 발생시킨 다음 Selector 클래스에서 처리한 다음 Selector 클래스에서 다른 라우트된 이벤트로 변환될 수 SelectionChanged있습니다.For instance, items within a Selector are expected to raise the attached Selected event, which is then class handled by the Selector class and then potentially converted by the Selector class into a different routed event, SelectionChanged. 라우트된 이벤트 및 클래스 처리에 대한 자세한 내용은 라우트된 이벤트를 처리된 것으로 표시 및 클래스 처리를 참조하십시오.For more information on routed events and class handling, see Marking Routed Events as Handled, and Class Handling.

연결된 이벤트를 라우트된 이벤트로 정의Defining Your Own Attached Events as Routed Events

일반적인 WPF 기본 클래스에서 파생되는 경우 클래스에 특정 패턴 메서드를 포함하고 기본 클래스에 이미 있는 유틸리티 메서드를 사용하여 고유한 연결된 이벤트를 구현할 수 있습니다.If you are deriving from common WPF base classes, you can implement your own attached events by including certain pattern methods in your class and by using utility methods that are already present on the base classes.

패턴은 다음과 같습니다.The pattern is as follows:

  • 두 개의 매개 변수가 있는 이벤트 이름처리기 추가 메서드입니다.A method AddEventNameHandler with two parameters. 첫 번째 매개 변수는 이벤트 처리기가 추가되는 인스턴스입니다.The first parameter is the instance to which the event handler is added. 두 번째 매개 변수는 추가할 이벤트 처리기입니다.The second parameter is the event handler to add. 메서드는 반환 public static값이 없어야 합니다.The method must be public and static, with no return value.

  • 두 개의 매개 변수를 사용하여 EventName처리기를 제거하는 메서드입니다.A method RemoveEventNameHandler with two parameters. 첫 번째 매개 변수는 이벤트 처리기가 제거되는 인스턴스입니다.The first parameter is the instance from which the event handler is removed. 두 번째 매개 변수는 제거할 이벤트 처리기입니다.The second parameter is the event handler to remove. 메서드는 반환 public static값이 없어야 합니다.The method must be public and static, with no return value.

EventNameEventName처리기 추가 접근자 메서드는 연결된 이벤트 처리기 특성이 요소에 선언될 때 XAML 처리를 용이하게 합니다.The AddEventNameHandler accessor method facilitates XAML processing when attached event handler attributes are declared on an element. 이벤트이름처리기 추가이벤트이름처리기 제거 메서드는 연결된 이벤트에 대한 이벤트 처리기 저장소에 대한 코드 액세스를 활성화합니다.The AddEventNameHandler and RemoveEventNameHandler methods also enable code access to the event handler store for the attached event.

주어진 XAML 판독기 구현에는 지원 언어 및 아키텍처에서 기본 이벤트를 식별하기 위한 다른 체계가 있을 수 있으므로 이 일반적인 패턴은 프레임워크에서 실제 구현하기에 충분하지 않습니다.This general pattern is not yet precise enough for practical implementation in a framework, because any given XAML reader implementation might have different schemes for identifying underlying events in the supporting language and architecture. WPF가 연결된 이벤트를 라우트된 이벤트로 구현하는 이유 중 하나입니다. 이벤트에 사용할 식별자 ()RoutedEvent이미 WPF 이벤트 시스템에 의해 정의되어 있습니다.This is one of the reasons that WPF implements attached events as routed events; the identifier to use for an event (RoutedEvent) is already defined by the WPF event system. 또한 이벤트를 라우팅하는 것은 연결된 이벤트의 XAML 언어 수준 개념에 대한 자연스러운 구현 확장입니다.Also, routing an event is a natural implementation extension on the XAML language-level concept of an attached event.

WPF 연결 된 이벤트에 대 한 추가EventName처리기 구현 라우트 된 이벤트 와 처리기를 인수로 호출 AddHandler 하는 구성 됩니다.The AddEventNameHandler implementation for a WPF attached event consists of calling the AddHandler with the routed event and handler as arguments.

이 구현 전략 및 라우트된 이벤트 시스템은 일반적으로 해당 UIElement 클래스만 ContentElement 구현을 갖기 AddHandler 때문에 연결된 이벤트에 대한 처리를 파생 클래스 또는 파생 클래스로 제한합니다.This implementation strategy and the routed event system in general restrict handling for attached events to either UIElement derived classes or ContentElement derived classes, because only those classes have AddHandler implementations.

예를 들어 다음 코드는 NeedsCleaning 연결된 이벤트를 라우트된 Aquarium이벤트로 선언하는 WPF 연결 이벤트 전략을 사용하여 소유자 클래스에서 연결된 이벤트를 정의합니다.For example, the following code defines the NeedsCleaning attached event on the owner class Aquarium, using the WPF attached event strategy of declaring the attached event as a routed event.

public static readonly RoutedEvent NeedsCleaningEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AquariumFilter));
public static void AddNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
    UIElement uie = d as UIElement;
    if (uie != null)
    {
        uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler);
    }
}
public static void RemoveNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
    UIElement uie = d as UIElement;
    if (uie != null)
    {
        uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler);
    }
}
Public Shared ReadOnly NeedsCleaningEvent As RoutedEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))
Public Shared Sub AddNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
    Dim uie As UIElement = TryCast(d, UIElement)
    If uie IsNot Nothing Then
        uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler)
    End If
End Sub
Public Shared Sub RemoveNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
    Dim uie As UIElement = TryCast(d, UIElement)
    If uie IsNot Nothing Then
        uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler)
    End If
End Sub

연결된 이벤트 식별자 필드를 RegisterRoutedEvent설정하는 데 사용되는 메서드는 실제로 연결되지 않은 라우트된 이벤트를 등록하는 데 사용되는 메서드와 동일합니다.Note that the method used to establish the attached event identifier field, RegisterRoutedEvent, is actually the same method that is used to register a non-attached routed event. 연결된 이벤트 및 라우트된 이벤트 모두 중앙 집중화된 내부 저장소에 등록됩니다.Attached events and routed events all are registered to a centralized internal store. 이 이벤트 저장소 구현은 라우트된 이벤트 개요에서 설명하는 “인터페이스로서의 이벤트” 개념 고려 사항을 사용합니다.This event store implementation enables the "events as an interface" conceptual consideration that is discussed in Routed Events Overview.

WPF 연결된 이벤트 발생Raising a WPF Attached Event

일반적으로 코드에서 기존 WPF 정의 연결된 이벤트를 발생시킬 필요가 없습니다.You do not typically need to raise existing WPF-defined attached events from your code. 이러한 이벤트는 일반적인 "서비스" 개념 모델을 따르며 이벤트 InputManager 발생과 같은 서비스 클래스는 이벤트를 발생시합니다.These events follow the general "service" conceptual model, and service classes such as InputManager are responsible for raising the events.

RoutedEvent그러나 에 연결된 이벤트의 WPF 모델을 기반으로 사용자 지정 연결 된 이벤트를 정의 RaiseEvent 하는 경우 모든 UIElement 또는 ContentElement에서 연결 된 이벤트를 발생 시킬 수 있습니다.However, if you are defining a custom attached event based on the WPF model of basing attached events on RoutedEvent, you can use RaiseEvent to raise an attached event from any UIElement or ContentElement. 라우트된 이벤트를 발생(연결 여부)하려면 요소 트리의 특정 요소를 이벤트 소스로 선언해야 합니다. 해당 소스가 RaiseEvent 호출자로 보고됩니다.Raising a routed event (attached or not) requires that you declare a particular element in the element tree as the event source; that source is reported as the RaiseEvent caller. 트리에서 소스로 보고되는 요소 판별은 서비스에 따라 다릅니다.Determining which element is reported as the source in the tree is your service's responsibility

참고 항목See also