연결된 이벤트 개요Attached Events Overview

Extensible Application Markup Language (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.

PrerequisitesPrerequisites

이 항목에서는 라우트된 이벤트 개요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 구문에서 연결 된 이벤트는 이벤트 이름 뿐만 아니라 해당 이벤트 이름에는 점 (.)으로 구분 된 이벤트 이름에 의해 지정 됩니다.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.

예를 들어, 기본 연결 된 이벤트 Mouse.MouseDown를 XAML 또는 코드에서 연결 된 이벤트 구문을 처리 하는 대신 해당 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. 예를 들어 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:

  • 메서드는 두 개의 매개 변수를 사용 하 여 EventName처리기를 추가 합니다.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.

AddEventNamehandler accessor 메서드는 요소에 연결 된 이벤트 처리기 특성이 선언 될 때 XAML 처리를 용이 하 게 합니다.The AddEventNameHandler accessor method facilitates XAML processing when attached event handler attributes are declared on an element. AddeventnameHandlerRemoveeventnamehandler 메서드를 사용 하 여 연결 된 이벤트에 대 한 이벤트 처리기 저장소에 코드에 액세스할 수도 있습니다.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 연결 된 이벤트에 대 한 AddEventNameHandler 구현은 라우트된 이벤트와 처리기를 인수로 사용 하 여 AddHandler를 호출 하는 것으로 구성 됩니다.The AddEventNameHandler implementation for a WPF attached event consists of calling the AddHandler with the routed event and handler as arguments.

일반적으로이 구현 전략과 라우트된 이벤트 시스템은 연결 된 이벤트에 대 한 처리를 파생 클래스 또는 ContentElement 파생 클래스 UIElement에 대 한 처리를 제한 합니다. 이러한 클래스에는 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.

예를 들어 다음 코드는 연결 된 이벤트를 라우트된 이벤트로 선언 하는 데 사용 되는 WPF 연결 이벤트 전략을 사용 하 여 소유자 클래스 Aquarium에서 NeedsCleaning 연결 된 이벤트를 정의 합니다.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