본문 바로가기

개인공부/WPF

[WPF] 이벤트 라우팅, 터널링(Tunneling), 버블링(Bubbling)

■ 이벤트 라우팅(Event Routing)이란?

이벤트 발생 시에 Element Tree의 여러 Element로 이벤트가 전달되는 것

이벤트는 터널링(Tunneling), 버블링(Bubbling), 다이렉트(Direct) 3가지로 분류됩니다.

 - 터널링(Tunneling) : 상위에서부터 이벤트 발생 요소(Element)로 이벤트 발생

 - 버블링(Bubbling) : 이벤트 발생 요소(Element)부터 상위로 이벤트 발생

 - 다이렉트(Direct) : 하나의 요소(Element)에서만 이벤트 발생

 

■ Event Routing Example

 - Example 설명

   · 4단계의 Grid 계층 구조 안에 button이 있는 구조

   · 좌, 우측 button 클릭 시 이벤트 발생 순서대로 가운데 TextBox에 출력

 

 - MainWindow.xaml

MainWindow.xaml 디자인

<Window x:Class="RoutedEventEx.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:RoutedEventEx"
        mc:Ignorable="d"
        Title="MainWindow" Height="400" Width="1000">
    <Window.Resources>
        <Style TargetType="UniformGrid">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
        </Style>
        <Style TargetType="Grid">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
        </Style>
        <Style TargetType="Label">
            <Setter Property="VerticalAlignment" Value="Top"/>
            <Setter Property="HorizontalAlignment" Value="Left"/>
            <Setter Property="Margin" Value="3,3,0,0"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid x:Name="TGrid01" Width="300" Height="300" Grid.Row="0" Grid.Column="0" 
              Background="LightCyan" ButtonBase.Click="grid01_Click">
            <Label Content="TGrid01"/>
            <Grid x:Name="TGrid02" Width="250" Height="250" Background="LightGoldenrodYellow" 
                  ButtonBase.Click="grid02_Click">
                <Label Content="TGrid02"/>
                <Grid x:Name="TGrid03" Width="200" Height="200" Background="LightGreen" 
                      ButtonBase.Click="grid03_Click">
                    <Label Content="TGrid03"/>
                    <Grid x:Name="TGrid04" Width="150" Height="150" Background="LightPink" 
                          ButtonBase.Click="grid04_Click">
                        <Label Content="TGrid04"/>
                        <Button Content="Tunneling Test" Width="100" Height="30" Click="T_Button_Click"/>
                    </Grid>
                </Grid>
            </Grid>
        </Grid>
        <!--▲ Tunneling Grid-->
        <!--▼ TextBox-->
        <StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
            <Label Content="◀ Tunneling Event"/>
            <TextBox x:Name="tunnelTbx" Grid.Row="0" Grid.Column="1" Width="200" Height="100" Margin="10,0,10,10"/>
            <Label HorizontalAlignment="Right" Content="Bubbleing  Event ▶"/>
            <TextBox x:Name="bubbleTbx" Grid.Row="0" Grid.Column="1" Width="200" Height="100" Margin="10,0,10,0"/>
        </StackPanel>
        <!--▲ TextBox-->
        <!--▼ bubbling Grid-->
        <Grid x:Name="BGrid01" Width="300" Height="300" Grid.Row="0" Grid.Column="2" 
              Background="LightCyan" PreviewMouseDown="grid01_Click">
            <Label Content="BGrid01"/>
            <Grid x:Name="BGrid02" Width="250" Height="250" Background="LightGoldenrodYellow" 
                  PreviewMouseDown="grid02_Click">
                <Label Content="BGrid02"/>
                <Grid x:Name="BGrid03" Width="200" Height="200" Background="LightGreen" 
                      PreviewMouseDown="grid03_Click">
                    <Label Content="BGrid03"/>
                    <Grid x:Name="BGrid04" Width="150" Height="150" Background="LightPink" 
                          PreviewMouseDown="grid04_Click">
                        <Label Content="BGrid04"/>
                        <Button Content="Bubbling Test" Width="100" Height="30" PreviewMouseDown="B_Button_Click"/>
                    </Grid>
                </Grid>
            </Grid>
        </Grid>
    </Grid>
    
    
</Window>

 

 

 

 - MainWindow.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace RoutedEventEx
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        
        private void grid01_Click(object sender, RoutedEventArgs e)
        {
            Grid grid = sender as Grid;
            string eventType = (grid.Name == "TGrid01") ? "Tunneling" : "Bubbling";
            InputText(eventType, grid);
        }

        private void grid02_Click(object sender, RoutedEventArgs e)
        {
            Grid grid = sender as Grid;
            string eventType = (grid.Name == "TGrid02") ? "Tunneling" : "Bubbling";
            InputText(eventType, grid);
        }
        private void grid03_Click(object sender, RoutedEventArgs e)
        {
            Grid grid = sender as Grid;
            string eventType = (grid.Name == "TGrid03") ? "Tunneling" : "Bubbling";
            InputText(eventType, grid);
            e.Handled = true;   // true이면 이벤트 전달 차단
        }
        private void grid04_Click(object sender, RoutedEventArgs e)
        {
            Grid grid = sender as Grid;
            string eventType = (grid.Name == "TGrid04") ? "Tunneling" : "Bubbling";
            InputText(eventType, grid);
        }

        private void InputText(string evnetType, Grid grid)
        {
            if (evnetType == "Tunneling")
                tunnelTbx.AppendText($"[Tunnling Event] {grid.Name}  \n");
            else
                bubbleTbx.AppendText($"[Bubbling Event] {grid.Name}  \n");
        }

        private void T_Button_Click(object sender, RoutedEventArgs e)
        {
            tunnelTbx.AppendText($"Button_Click event!! \n");
        }

        private void B_Button_Click(object sender, RoutedEventArgs e)
        {
            bubbleTbx.AppendText($"Button_Click event!! \n");
        }
    }
}

 - 좌측 버튼(Tunneling Test) 클릭, 최상위 요소(TGrid01)부터 이벤트 발생 요소(Button) 순서로 이벤트 발생

 - TGrid03에서 이벤트 전달 차단 

 - 이벤트 발생 순서대로 가운데 TextBox에 출력

 

 - 측 버튼(Bubbling Test) 클릭, 이벤트 발생 요소(Button)부터 최상위(BGrid01) 순서로 이벤트 발생 

 - TGrid03에서 이벤트 전달 차단

 - 이벤트 발생 순서대로 가운데 TextBox에 출력

 

 

 

'개인공부 > WPF' 카테고리의 다른 글

[WPF] DataContext  (0) 2022.07.23
[WPF] 의존 속성(DependencyProperty)  (0) 2022.05.20
[WPF] 멀티쓰레드(Multi Thread)  (0) 2022.05.11
[WPF] 데이터 바인딩(Data Binding)  (0) 2022.04.26
[WPF] Hello World  (0) 2022.04.19