다음을 통해 공유


방법: 라우트된 이벤트에 대한 클래스 처리 추가

라우트된 이벤트는 경로의 지정된 노드에서 클래스 처리기 또는 인스턴스 처리기를 통해 처리할 수 있습니다. 클래스 처리기는 먼저 호출되며, 클래스 구현에서 인스턴스 처리로 인한 이벤트를 표시하지 않거나 기본 클래스가 소유한 이벤트에 대해 다른 이벤트 관련 동작을 도입하는 데 사용할 수 있습니다. 이 예제에서는 클래스 처리기를 구현하기 위한 두 가지 밀접하게 관련된 기술을 보여 줍니다.

예제

이 예제에서는 Canvas 패널을 기반으로 사용자 지정 클래스를 사용합니다. 애플리케이션의 기본 전제는 자식 요소 클래스나 이에 대한 인스턴스 처리기가 호출되기 전에 사용자 지정 클래스가 마우스 왼쪽 단추 클릭을 가로채고 처리된 것으로 표시하는 등 자식 요소에 대한 동작을 도입한다는 것입니다.

UIElement 클래스는 단순히 이벤트를 재정의하여 PreviewMouseLeftButtonDown 이벤트에 대한 클래스 처리를 가능하게 하는 가상 메서드를 노출합니다. 이는 클래스 계층 구조의 어딘가에 가상 메서드를 사용할 수 있는 경우 클래스 처리를 구현하는 가장 간단한 방법입니다. 다음 코드는 Canvas에서 파생된 “MyEditContainer”의 OnPreviewMouseLeftButtonDown 구현을 보여 줍니다. 구현은 인수에서 이벤트를 처리된 것으로 표시한 다음, 일부 코드를 추가하여 원본 요소에 기본 시각적 변경을 제공합니다.

protected override void OnPreviewMouseRightButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
    e.Handled = true; //suppress the click event and other leftmousebuttondown responders
    MyEditContainer ec = (MyEditContainer)e.Source;
    if (ec.EditState)
    { ec.EditState = false; }
    else
    { ec.EditState = true; }
    base.OnPreviewMouseRightButtonDown(e);
}
Protected Overrides Sub OnPreviewMouseRightButtonDown(ByVal e As System.Windows.Input.MouseButtonEventArgs)
    e.Handled = True 'suppress the click event and other leftmousebuttondown responders
    Dim ec As MyEditContainer = CType(e.Source, MyEditContainer)
    If ec.EditState Then
        ec.EditState = False
    Else
        ec.EditState = True
    End If
    MyBase.OnPreviewMouseRightButtonDown(e)
End Sub

기본 클래스 또는 특정 메서드에서 가상을 사용할 수 없는 경우 EventManager 클래스의 유틸리티 메서드 RegisterClassHandler를 사용하여 클래스 처리를 직접 추가할 수 있습니다. 이 메서드는 클래스 처리를 추가하는 클래스의 정적 초기화 내에서만 호출되어야 합니다. 이 예제에서는 PreviewMouseLeftButtonDown에 대한 다른 처리기를 추가하며 이 경우 등록된 클래스는 사용자 지정 클래스입니다. 반면, 가상을 사용할 때 등록된 클래스는 실제로 UIElement 기본 클래스입니다. 기본 클래스와 서브클래스가 각각 클래스 처리를 등록하는 경우 서브클래스 처리기가 먼저 호출됩니다. 애플리케이션의 동작은 먼저 이 처리기가 메시지 상자를 표시한 다음, 가상 메서드 처리기의 시각적 변경 내용이 표시되는 것입니다.

static MyEditContainer()
{
  EventManager.RegisterClassHandler(typeof(MyEditContainer), PreviewMouseRightButtonDownEvent, new RoutedEventHandler(LocalOnMouseRightButtonDown));
}
internal static void LocalOnMouseRightButtonDown(object sender, RoutedEventArgs e)
{
  MessageBox.Show("this is invoked before the On* class handler on UIElement");
  //e.Handled = true; //uncommenting this would cause ONLY the subclass' class handler to respond
}
Shared Sub New()
    EventManager.RegisterClassHandler(GetType(MyEditContainer), PreviewMouseRightButtonDownEvent, New RoutedEventHandler(AddressOf LocalOnMouseRightButtonDown))
End Sub
Friend Shared Sub LocalOnMouseRightButtonDown(ByVal sender As Object, ByVal e As RoutedEventArgs)
    MessageBox.Show("this is invoked before the On* class handler on UIElement")
    'e.Handled = True //uncommenting this would cause ONLY the subclass' class handler to respond
End Sub

참고 항목