티스토리 뷰
1. Trigger Overview
Trigger는 컨트롤의 시각적 효과를 변경하는 데 도움이 되는 WPF의 매우 중요한 기능입니다. 트리거를 이용해서 속성 변경, 데이터 변경, 이벤트 발생 시점에 컨트롤의 시각적 효과를 변경하기 위해 사용되며, Code behind나 ViewModel에서 시각적 효과를 변경하기 위한 동작을 최소화 할 수 있습니다. 물론 Xaml의 코딩량이 그 만큼 늘어나지만, UI와 비지니스 로직의 분리라는 측면에서 보면 매우 좋은 기능입니다.
2. Trigger 종류 및 사용법
종류
- Property Trigger(Trigger)
- WPF의 기본 트리거이며 <Trigger/>로 사용할 수 있습니다.
- Trigger를 소유한 컨트롤의 속성 값이 변경될 때 동작합니다. 다른 컨트롤의 속성값을 사용할 수 없습니다.
- 의존속성(DependencyProperty)만 사용이 가능합니다.
- Binding을 사용할 수 없습니다.
- 여러개의 조건을 사용하기 위해서는 <MultiTrigger/>를 이용합니다.
- Data Trigger
- <DataTrigger/>로 사용할 수 있습니다.
- Binding 기능을 이용하여 데이터와 연결할 수 있으며, 그 데이터가 변경되면 동작합니다.
- 의존속성(DependencyProperty)과 일반 속성(Public Property)를 모두 사용할 수 있습니다.
- 접근 가능 범위내 다른 컨트롤의 속성을 사용할 수 있습니다.
- 여러개의 조건을 사용하기 위해서는 <MultiDataTrigger/>를 이용합니다.
- Event Trigger
- <EventTrigger/>로 사용할 수 있습니다.
- Trigger를 소유한 컨트롤의 이벤트가 발생될 때 동작합니다.
- 트리거 발생시 Storyboard를 이용해서 프로퍼티 값을 수정하기 때문에 코드가 길어지고, 사용이 불편합니다. 이 경우에는 아래 Microsoft.Xaml.Behaviors.Wpf의 Trigger 사용하는 것을 권장합니다.
- Microsoft.Xaml.Behaviors.Wpf의 Trigger 사용
사용
- Style 내부에서 사용
- 가장 일반적인 사용법
- <Style.Triggers></Style.Triggers> 내부에서 사용합니다.
- 각 컨트롤마다 Style Trigger를 지정하거나, Resources에 정의해서 사용합니다.
- DataTemplate에서 사용 (ItemTemplate 등에 사용됩니다.)
- <DataTemplate.Triggers></DataTemplate.Triggers> 내부에 사용합니다.
- DataTemplate 제일 하단부에 추가할 수 있으며, DataTemplate 내부의 각 컨트롤들을 제어할 수 있는 코드를 작성할 수 있습니다.
- ContentTemplate에서 사용 (Content 프로퍼티 내부에 템플릿을 지정하는데 사용됩니다.)
- <ContentTemplate.Triggers></ContentTemplate.Triggers> 내부에 사용합니다.
- ContentTemplate 제일 하단부에 추가할 수 있으며, ContentTemplate 내부의 각 컨트롤들을 제어할 수 있는 코드를 작성할 수 있습니다.
- ControlTemplate에서 사용하기 (Control의 UI 구성을 변경하기위해 사용합니다.)
- <ControlTemplate.Triggers></ControlTemplate.Triggers> 내부에 사용합니다.
- ControlTemplate 제일 하단부에 추가할 수 있으며, ControlTemplate 내부의 각 컨트롤들을 제어할 수 있는 코드를 작성할 수 있습니다.
3. ListBox에서 선택된 아이템 스타일 변경
ListBox에서 데이터를 표시할 때 각 각의 Item들은 ListBoxItem이라는 Control이 만들어지면서, 데이터가 표시 됩니다.
데이터가 표시되는 컨트롤을 통칭해서 ItemContainer라 하고, ListBox의 ListBoxItem의 스타일을 입력하기 위해서는 <ListBox.ItemContainerStyle/>을 이용합니다.
3rd party 컨트롤 중 일부는 전혀 다른 이름의 프로퍼티를 이용해야지 Item의 Style을 변경 할 수 있습니다.
처음으로 사용해볼 트리거는 <Trigger/>입니다.
- Grid를 2개의 컬럼으로 나누고, 첫번째 컬럼에 ListBox에 ListBox.ItemContainerStyle을 이용해서 Style을 추가 합니다.
- Style의 TargetType을 반드시 지정해야 합니다.
- 첫번째 Setter는 HorizontalContentAlignment라는 속성의 값을 Stretch로 변경합니다. 기본 값은 Left입니다.
- Trigger를 사용해서 ListBoxItem의 IsSelected라는 속성의 값이 True이면, 아래있는 Setter 2개를 실행하게 됩니다.
- 해당 조건에 만족하는 Item에 대해서만 수행하고, 다른 Item을 선택하면 이전 아이템의 스타일은 원래 상태로 변경됩니다.
ListBoxItem의 Background 컬러는 컨트롤 내부에 기본 트리거로 인해 이 방법으로는 변경할 수 없습니다. 나중에 이 부분에 대해서 설명 드리겠습니다.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListBox DisplayMemberPath="Name" ItemsSource="{Binding People}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="15" />
<Setter Property="BorderThickness" Value="3" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<ListBox
Grid.Column="1"
DisplayMemberPath="Name"
ItemsSource="{Binding People}" />
</Grid>
실행
아이템 선택
4. ItemTemplate를 이용해서 추가 효과 주기
위에서 다루었던 내용은 ListBoxItem이라는 컨트롤의 Style을 변경하는 것이였는데, 내부 컨텐츠를 좀더 다양하게 변화 시키기 위해서는 직접 ItemTemplate를 만들고 효과를 추가하는 것이 더 좋습니다.
Window.Resources에 DataTemplate를 하나 추가 합니다.
- TextBlock의 스타일을 변경하기 위한 트리거는 ListBoxItem의 IsSelected 프로퍼티이기 때문에 해당 프로퍼티를 감시하려면, DataTrigger와 Binding을 이용해야 합니다.
- Binding에는 RelativeSource를 사용하면 됩니다.
- 트리거가 발동되면, TextBlock의 2개의 속성 값을 변경합니다.
<DataTemplate x:Key="ListBoxItemTemplate2">
<TextBlock x:Name="NameTextBlock2" Text="{Binding Name}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
Value="True">
<Setter Property="TextAlignment" Value="Right" />
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
Binding이 어려운 분들을 위한 팁
Xaml에서 커서를 DataTrigger로 이동합니다.
오른쪽 프로퍼티 창에 Binding 이란 속성 오른쪽 끝에 원통 아이콘을 클릭합니다.
데이터 바인딩을 쉽게 만들어주는 창이 출력됩니다.
이 창을 이용해서 바인딩을 만들면 훨씬 빠르고 쉽게 만들 수 있습니다.
창 이미지와 아래 내용이 서로 연결되는 것을 알 수 있습니다.
Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
옛날에 저도 이 방법으로 대부분 바인딩 만들어서 사용했습니다. ㅎㅎㅎㅎ
DisplayMemberPath를 지우고, ItemTemplate를 연결합니다.
<ListBox ItemTemplate="{StaticResource ListBoxItemTemplate2}" ItemsSource="{Binding People}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="15" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
실행
5. 소스
WpfTest/TriggerSample1 at master · kaki104/WpfTest (github.com)
'WPF .NET' 카테고리의 다른 글
Trigger를 사용해서 동적 UI 구성하기 Part3 - DataTrigger (0) | 2022.12.29 |
---|---|
Trigger를 사용해서 동적 UI 구성하기 Part2 (0) | 2022.12.21 |
Microsoft.Toolkit.MVVM을 이용한 간단한 프레임워크 part7 - Windows Community Toolkit Upgrade (2) | 2022.12.12 |
Prism Library를 사용하는 개발자를 위한 안내 Part7 - Create RegionAdapter (0) | 2022.12.06 |
Prism Library를 사용하는 개발자를 위한 안내 Part6 - TabControl Region Navigation (0) | 2022.11.30 |
- Total
- Today
- Yesterday
- LINQ
- Cross-platform
- Windows 10
- XAML
- kiosk
- C#
- Always Encrypted
- #MVVM
- .net 5.0
- ComboBox
- Microsoft
- windows 11
- PRISM
- ef core
- #prism
- IOT
- Bot Framework
- dotNETconf
- MVVM
- WPF
- UWP
- Behavior
- uno-platform
- Visual Studio 2022
- #uwp
- uno platform
- visual studio 2019
- #Windows Template Studio
- .net
- Build 2016
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |