본문 바로가기
Languages/C#

Day 5: 이벤트 처리 - 이벤트 핸들러 등록 및 제거, 이벤트 전파

by 반도체는 프로그래밍을 좋아해 2023. 4. 5.
728x90

 

WPF 과정 Day 5: 이벤트 처리 - 이벤트 핸들러 등록 및 제거, 이벤트 전파

이벤트는 UI 요소에서 발생하는 모든 동작을 나타내며, 이벤트 처리는 WPF 애플리케이션에서 중요한 역할을 합니다. 이번 강좌에서는 이벤트 처리의 기초적인 개념과 함께 이벤트 핸들러 등록 및 제거, 이벤트 전파에 대해 살펴보겠습니다.

이벤트 핸들러 등록

이벤트 핸들러를 등록하는 가장 일반적인 방법은 XAML에서 이벤트를 선언하고 코드에서 해당 이벤트에 대한 핸들러를 연결하는 것입니다. 이벤트 핸들러를 등록하는 방법은 두 가지가 있습니다.

1. 이벤트 속성을 사용하여 이벤트 핸들러 등록하기

<Button Content="Click Me" Click="ButtonClickHandler" />

위 코드에서는 Button의 Click 이벤트에 대한 핸들러로 ButtonClickHandler 메서드를 등록합니다.

2. 이벤트 핸들러 메서드를 코드에서 직접 등록하기

Button button = new Button();
button.Click += ButtonClickHandler;

위 코드에서는 Button의 Click 이벤트에 대한 핸들러로 ButtonClickHandler 메서드를 직접 등록합니다.

이벤트 핸들러 제거

이벤트 핸들러를 제거하는 방법은 등록하는 방법과 유사합니다. 먼저 XAML에서 이벤트를 선언하는 방법입니다.

<Button Content="Click Me" Click="ButtonClickHandler" />

위 코드에서는 Button의 Click 이벤트에 대한 핸들러로 ButtonClickHandler 메서드를 등록합니다. 핸들러를 제거하려면 Click 이벤트를 null로 설정합니다.

<Button Content="Click Me" Click="{x:Null}" />

코드에서 직접 등록한 핸들러를 제거하려면 마찬가지로 -= 연산자를 사용합니다.

Button button = new Button();
button.Click -= ButtonClickHandler;

이벤트 전파

WPF에서 이벤트는 특정 UI 요소에서 발생하면 상위 요소로 전파됩니다. 이벤트 전파는 두 가지가지 방법이 있습니다. 바로 버블링(bubbling)터널링(tunneling)입니다.

버블링은 이벤트가 발생한 요소에서 상위 요소로 이벤트가 전파되는 방식입니다. 예를 들어, Button에서 클릭 이벤트가 발생하면, 버튼에 대한 클릭 이벤트 처리가 끝난 후 상위 요소인 Grid, Window 등으로 이벤트가 전파됩니다.

반면에 터널링은 상위 요소에서 하위 요소로 이벤트가 전파되는 방식입니다. 예를 들어, Grid에서 마우스 클릭 이벤트가 발생하면, Grid에 대한 마우스 클릭 이벤트 처리가 끝난 후 Grid의 하위 요소인 Button 등으로 이벤트가 전파됩니다.

이벤트 전파 방식은 이벤트 처리 중첩 구조를 통해 상위 요소에서 하위 요소로 또는 하위 요소에서 상위 요소로 이벤트를 전달하는 데 사용됩니다. 이는 이벤트 처리 중첩 구조에서 다양한 요소에서 이벤트를 처리하도록 허용하며, 이벤트의 전파를 조절함으로써 유연성을 제공합니다.

WPF에서는 Preview 이벤트라는 것도 있습니다. Preview 이벤트는 터널링 이벤트와 유사하지만, 이벤트가 발생하기 전에 먼저 상위 요소로 전파됩니다. 예를 들어, PreviewMouseDown 이벤트는 마우스 버튼이 눌려지기 전에 먼저 Window에서 발생하고, 그 다음으로 하위 요소로 전파됩니다.

아래는 WPF에서 이벤트 전파 방식을 활용한 예시 코드입니다.

<Grid MouseDown="Grid_MouseDown">
    <Button Click="Button_Click">Click me!</Button>
</Grid>

private void Grid_MouseDown(object sender,MouseEventArgs e)
{
// Grid에서 마우스 다운 이벤트가 발생했을 때 실행되는 코드
Debug.WriteLine("Grid mouse down!");
// 이벤트를 계속 전파하려면 e.Handled 속성을 false로 유지합니다.
// 이 경우, Button의 Click 이벤트도 발생합니다.
}

private void Button_Click(object sender, RoutedEventArgs e)
{
// Button에서 클릭 이벤트가 발생했을 때 실행되는 코드
Debug.WriteLine("Button clicked!");
// 이벤트 처리를 여기서 중지하려면 e.Handled 속성을 true로 변경합니다.
// 이 경우, 상위 요소인 Grid의 MouseDown 이벤트는 발생하지 않습니다.
}

위 예시 코드에서는 GridButton 요소에 각각 MouseDown 이벤트와 Click 이벤트를 등록하고 있습니다. GridMouseDown 이벤트는 터널링 이벤트이므로 Grid에서 발생하고, ButtonClick 이벤트는 버블링 이벤트이므로 Button에서 발생합니다.

<Grid MouseDown="Grid_MouseDown">
    <Button Click="Button_Click">Click me!</Button>
</Grid>

private void Grid_MouseDown(object sender,
MouseEventArgs e)
{
    Debug.WriteLine("Grid mouse down!");
    e.Handled = false;
}

private void Button_Click(object sender,
RoutedEventArgs e)
{
    Debug.WriteLine("Button clicked!");
    e.Handled = true;
}

GridMouseDown 이벤트 핸들러에서는 "Grid mouse down!"이라는 디버그 출력을 남기고 있습니다. 이벤트를 계속 전파하려면 핸들러에서 e.Handled 속성을 false로 유지하면 됩니다. 이 경우, ButtonClick 이벤트도 발생합니다.

ButtonClick 이벤트 핸들러에서는 "Button clicked!"라는 디버그 출력을 남기고 있습니다. 이벤트 처리를 여기서 중지하려면 핸들러에서 e.Handled 속성을 true로 변경하면 됩니다. 이 경우, 상위 요소인 GridMouseDown 이벤트는 발생하지 않습니다.

이와 같이 WPF에서 이벤트 전파 방식을 활용하면 다양한 이벤트 처리 요구사항에 유연하게 대처할 수 있습니다.

728x90