(WPF) 6. WPF에서 트리거와 데이터 트리거 활용하기
트리거를 활용한 스타일 및 데이터 연동 방법
트리거(Trigger) 개요
WPF에서 트리거(Trigger)는 특정 이벤트나 속성 값의 변화가 발생했을 때, 미리 정의된 스타일을 자동으로 적용하여 UI를 동적으로 변경할 수 있는 기능이다. 대표적인 사용 예는 버튼 클릭, 마우스 오버, 컨트롤 활성화 여부 등에 따라 컨트롤의 스타일을 변경하는 경우가 있다.
트리거를 활용한 스타일 변경
아래의 예제는 버튼 위에 마우스를 올리거나 클릭했을 때 글자 색상을 변경하는 방법을 보여준다.
1
2
3
4
5
6
7
8
9
10
11
12
<Style x:Key="ButtonTriggerStyle" TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Green"/>
</Trigger>
<Trigger Property="IsMouseCaptureWithin" Value="True">
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
<Button Content="트리거 테스트" Style="{StaticResource ButtonTriggerStyle}" />
- 마우스가 올라가면 글자색이 초록색으로 변경된다.
- 버튼을 클릭하고 있는 동안에는 글자색이 파란색으로 변경된다.
한 가지 주의할 점이 있다. 같은 속성을 설정하는 트리거가 여러 개 동시에 활성화되면 나중에 선언된 트리거가 우선한다. 클릭 중에는 IsMouseOver와 IsMouseCaptureWithin이 둘 다 true이므로, 클릭 상태를 나타내는 트리거를 IsMouseOver 트리거보다 뒤에 선언해야 파란색이 적용된다. 순서가 반대라면 클릭 중에도 글자색은 초록색으로 유지된다.
데이터 트리거(DataTrigger)를 통한 컨트롤 상태 변경
데이터 트리거(DataTrigger)는 특정 데이터의 상태나 다른 컨트롤의 속성 값이 변경될 때 이를 감지하여 UI의 스타일 또는 상태를 변경한다. 예를 들어, 체크박스를 선택하면 버튼의 글자 색상과 활성 상태를 변경하는 방법을 아래에서 확인할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<CheckBox x:Name="CheckBox1" Content="버튼 비활성화"/>
<Button Content="테스트 버튼">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=CheckBox1, Path=IsChecked}" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
위의 예제를 실행하면 체크박스를 선택할 경우 버튼의 글자가 빨간색으로 변경되고 버튼이 비활성화된다.
INotifyPropertyChanged와 데이터 트리거 활용
데이터 트리거는 MVVM 패턴에서 ViewModel의 속성 값 변경에 따라 View를 동적으로 변경하는 데 사용된다. INotifyPropertyChanged 인터페이스를 통해 데이터의 변화를 View에 즉시 반영할 수 있다.
ViewModel 클래스 생성 과정
MVVM 패턴을 명확히 활용하기 위해 ViewModel 클래스는 일반적으로 프로젝트 내의 ViewModels라는 별도의 폴더에 생성한다. 다음과 같은 순서를 따른다.
- 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 버튼으로 클릭하고, 새 폴더를 선택한 후 폴더명을
ViewModels로 설정한다. ViewModels폴더를 마우스 오른쪽 버튼으로 클릭하고, 추가 → 클래스를 선택한다.- 클래스 이름을
MainViewModel로 입력하고 추가 버튼을 클릭한다.
MainViewModel 클래스 작성 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfAppProject.ViewModels
{
public class MainViewModel : INotifyPropertyChanged
{
private int progressValue;
public int ProgressValue
{
get => progressValue;
set
{
if (progressValue != value)
{
progressValue = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
View와 ViewModel 연결
아래는 MainWindow 코드에서 ViewModel과 View를 연결하는 방법이다.
1
2
3
4
5
6
7
8
9
10
11
public MainWindow()
{
InitializeComponent();
var mainViewModel = new MainViewModel { ProgressValue = 30 };
DataContext = mainViewModel;
}
private void btnTest1_Click(object sender, RoutedEventArgs e)
{
((MainViewModel)DataContext).ProgressValue = 100;
}
데이터 트리거를 이용한 상태 변경
아래 예제는 프로그레스 바의 값이 100일 때 자동으로 프로그레스 바를 숨기도록 하는 데이터 트리거 설정 방법이다.
1
2
3
4
5
6
7
8
9
10
11
<ProgressBar x:Name="progressBar1" Minimum="0" Maximum="100" Value="{Binding ProgressValue}" Height="20">
<ProgressBar.Style>
<Style TargetType="ProgressBar">
<Style.Triggers>
<DataTrigger Binding="{Binding Value, ElementName=progressBar1}" Value="100">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ProgressBar.Style>
</ProgressBar>
이 설정을 통해 프로그레스 바가 작업 완료(100%) 시 자동으로 숨겨진다.