26
WPF에서 버블 이벤트(Bubbling Event)와 터널 이벤트(Tunneling Event)는 WPF의 강력한 라우팅 이벤트(Routed Events) 기능의 일환으로, 이벤트가 컨트롤 트리를 통해 전파되는 방식과 관련이 있습니다.
- 버블 이벤트: 이벤트가 자식 컨트롤에서 부모 컨트롤로 전파됩니다.
- 터널 이벤트: 이벤트가 **루트 컨트롤(부모)**에서 자식 컨트롤로 전파됩니다.
이를 통해 여러 컨트롤이 동일한 이벤트를 처리하거나 이벤트 전파를 중단할 수 있습니다.
컨트롤 트리를 이동한다는 의미
- 컨트롤 트리:
- WPF는 XAML에서 정의된 UI를 논리적 트리(Logical Tree)와 시각적 트리(Visual Tree)로 표현합니다.
- 컨트롤 트리 이동은 이벤트가 트리 구조를 따라 전파되는 것을 의미합니다.
- 이벤트 전파 방식:
- 버블 이벤트: 이벤트는 발생한 요소에서 시작해 부모 컨트롤 방향으로 전파됩니다.
- 터널 이벤트: 이벤트는 루트(창이나 컨테이너)에서 자식 컨트롤 방향으로 내려갑니다.
버블 및 터널 이벤트의 사용 사례
- 버블 이벤트:
- 버튼 클릭과 같은 이벤트가 부모 컨트롤(예:
Grid
,Window
)에서 처리되어야 할 때 사용.
- 버튼 클릭과 같은 이벤트가 부모 컨트롤(예:
- 터널 이벤트:
- 이벤트가 자식 컨트롤로 전달되기 전에 부모 컨트롤이 먼저 처리해야 할 경우 사용.
예제 코드
버블 이벤트
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Bubble Event Example" Height="200" Width="400"
PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown"
MouseLeftButtonDown="Window_MouseLeftButtonDown">
<Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown">
<Button Content="Click Me!" HorizontalAlignment="Center" VerticalAlignment="Center"
MouseLeftButtonDown="Button_MouseLeftButtonDown"/>
</Grid>
</Window>
코드 비하인드
using System.Windows;
using System.Windows.Input;
namespace WpfApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// Button에서 이벤트 발생
private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Button MouseLeftButtonDown (Bubbling)");
}
// Grid로 이벤트 전파
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Grid MouseLeftButtonDown (Bubbling)");
}
// Window로 이벤트 전파
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Window MouseLeftButtonDown (Bubbling)");
}
}
}
실행 사진
터널 이벤트
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Tunneling Event Example" Height="200" Width="400"
PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown">
<Grid PreviewMouseLeftButtonDown="Grid_PreviewMouseLeftButtonDown">
<Button Content="Click Me!" HorizontalAlignment="Center" VerticalAlignment="Center"
PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown"/>
</Grid>
</Window>
코드 비하인드
using System.Windows;
using System.Windows.Input;
namespace WpfApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// Window에서 터널링 이벤트 발생
private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Window PreviewMouseLeftButtonDown (Tunneling)");
}
// Grid로 이벤트 전파
private void Grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Grid PreviewMouseLeftButtonDown (Tunneling)");
}
// Button으로 이벤트 전파
private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Button PreviewMouseLeftButtonDown (Tunneling)");
}
}
}
실행 사진
결과 및 실행 흐름
- 버블 이벤트:
- 이벤트가 자식에서 시작해 부모로 전파됩니다.
- 실행 순서:
Button
→Grid
→Window
.
- 터널 이벤트:
- 이벤트가 부모에서 시작해 자식으로 전파됩니다.
- 실행 순서:
Window
→Grid
→Button
.
이벤트 전파 중단
- 이벤트 전파를 중단하려면
e.Handled = true;
를 사용합니다.
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true; // 이벤트 전파 중단
MessageBox.Show("Event handled at Grid level");
}
요약
- 버블 이벤트: 자식에서 부모로 전파, 일반적인 이벤트 처리 방식.
- 터널 이벤트: 부모에서 자식으로 전파, 초기 제어 로직에 적합.
- 컨트롤 트리 이동: 이벤트가 논리적/시각적 트리 구조를 따라 이동하며 여러 컨트롤에서 처리 가능.