해당 포스팅은 개인적으로 C# WPF를 공부하면서 익힌 내용을 기억에 남기기 위한 작업의 일환으로 작성된 글로서 일부 내용에 오류가 있을 수도 있으니 참고하시기 바랍니다.
C# WPF에서 이벤트가 발생했을 때
그 이벤트가 어떻게 전달되는지에 대해
알아보도록 하자.
내용 요약
WPF (Windows Presentation Foundation)에서 이벤트는
사용자 인터페이스 요소 간의 상호작용을 처리하는 중요한 메커니즘이다.
WPF 이벤트 시스템은 두 가지 주요 유형의 라우팅 이벤트를 제공하는데,
여기서 등장하는 개념이
터널링(Tunneling) 이벤트와 버블링(Bubbling) 이벤트이다.
이 두 이벤트는 이벤트가 발생했을 때
이벤트가 어떻게 전파되는지를 정의한다.
목차
1.개념 정의(터널링, 버블링)
2.실습 예제 및 실행 결과
1.개념 정의(터널링, 버블링)
터널링 이벤트 (Tunneling Event)
터널링 이벤트는
루트 요소에서 시작하여 이벤트가 발생한 실제 요소까지 내려가는
이벤트이다.
다시말해, xaml 코드상에서 <Grid></Grid>로 묶여있는 곳 내부에
<StackPanel></StackPanel>로 묶여있고, 또 그 내부에
<TextBlock/> 혹은 <Button/>등이
정의 되어있다면, Grid → StackPanel → TextBlock or Button 으로
하방으로 이벤트가 전달되는 것을 뜻하는 것이다.
WPF에서는 터널링 이벤트의 이름이 "Preview"로 시작한다고 한다.
예를 들어, PreviewMouseDown 이벤트는
마우스 버튼이 눌렸을 때 발생하는 터널링 이벤트인 것이다.
버블링 이벤트 (Bubbling Event)
버블링 이벤트는
이벤트가 발생한 실제 요소에서 시작하여 루트 요소까지 올라가는 이벤트이다.
다시 말해, 터널링 이벤트와 정확히 반대 개념으로
작용하는 이벤트인 것이다.
TextBlock or Button → StackPanel → Grid
처럼 말이다.
버블링 이벤트의 한 예로
MouseDown 이벤트는
마우스 버튼이 눌렸을 때 발생하는 버블링 이벤트입니다.
2.실습 예제 및 실행 결과
WPF MVVM 패턴을 사용하여
터널링 이벤트와 버블링 이벤트를 설명하는 간단한 예제 프로그램을 작성하고
그 실행 결과를 살펴보자.
ViewModel
ViewModel은 INotifyPropertyChanged 인터페이스가 구현되어있는
BaseViewModel을 상속하여 데이터 바인딩을 지원하도록 하였다.
using System.ComponentModel;
namespace WpfApp
{
public class MainViewModel : INotifyPropertyChanged
{
private string _message;
public string Message
{
get { return _message; }
set
{
_message = value;
OnPropertyChanged(nameof(Message));
}
}
public MainViewModel()
{
Message = "Click on the buttons to see event handling.";
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
xmal 코드는 아래와 같이 작성하였다.
Grid 내에 StackPanel이 있고, 그 안에 TextBLock과 Button이 있다.
<Window x:Class="WpfApp.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:WpfApp"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<StackPanel>
<TextBlock Text="{Binding Message}" Margin="10" />
<Button Content="Click Me" PreviewMouseDown="Button_PreviewMouseDown" MouseDown="Button_MouseDown" Margin="10" />
</StackPanel>
</Grid>
</Window>
using System.Windows;
using System.Windows.Input;
namespace WpfApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var viewModel = DataContext as MainViewModel;
if (viewModel != null)
{
viewModel.Message = "PreviewMouseDown event triggered!";
}
}
private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
var viewModel = DataContext as MainViewModel;
if (viewModel != null)
{
viewModel.Message = "MouseDown event triggered!";
}
}
}
}
설명
PreviewMouseDown 이벤트: 이 이벤트는 터널링 이벤트로, 루트 요소에서 시작하여 실제 요소인 버튼까지 내려갑니다. 이 예제에서는 Button_PreviewMouseDown 메서드가 이 이벤트를 처리합니다.
MouseDown 이벤트: 이 이벤트는 버블링 이벤트로, 실제 요소인 버튼에서 시작하여 루트 요소까지 올라갑니다. 이 예제에서는 Button_MouseDown 메서드가 이 이벤트를 처리합니다.
실행 결과
프로그램을 실행하고 버튼을 클릭하면, 먼저 PreviewMouseDown 이벤트가 발생하여 "PreviewMouseDown event triggered!" 메시지가 표시됩니다. 그런 다음 MouseDown 이벤트가 발생하여 "MouseDown event triggered!" 메시지가 표시됩니다.
이 예제는 WPF에서 터널링 이벤트와 버블링 이벤트가 어떻게 작동하는지, 그리고 MVVM 패턴을 사용하여 이벤트를 처리하는 방법을 보여줍니다. 이를 통해 WPF 애플리케이션에서 이벤트를 효과적으로 관리하고 처리할 수 있습니다.
'프로그래밍 > C# (WPF)' 카테고리의 다른 글
C# WPF에서 delegate와 event에 대하여 - 1/2 (3) | 2024.11.13 |
---|---|
C# WPF에서 Grid내에 Row/Column을 자동 Align하는 방법에 대하여 (7) | 2024.11.11 |
RelayCommand에서 사용하는 Action, Func, Delegate 설명 (0) | 2024.10.26 |
C# WPF에서 필드(field)와 속성(property)에 대해 알아보고 get/set 개념 이해하기 (2) | 2024.10.12 |
C# WPF에 Style과 Trigger 설명 추가 (4) | 2024.10.09 |