티스토리 뷰
2022.09.06 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내v1.0 part9-2 StyleSelector
2022.08.31 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part9-1 DataTemplateSelector
2022.08.08 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part8-3 Template
2022.08.02 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part8-2 Template
2022.07.21 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part8-1 Template
2022.07.13 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part7 Behavior
2022.07.05 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part6 Command
2022.06.27 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part5 Converter
2022.06.15 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part4-2 Data Binding
2022.06.13 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part4-1 Data Binding
2022.06.07 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part3-3
2022.06.02 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part3-2
2022.05.30 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part3-1
2022.05.11 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part2
2022.05.09 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part1
1. Template
WPF(Xaml base ui)에서는 재사용이 가능한 템플릿(Template)을 사용하여 기존 컨트롤의 시각적 구조와 동작을 사용자가 지정할 수 있습니다. 더 자세한 사항은 여기를 참고하시기 바랍니다.
Control
- ControlTemplate
- 컨트롤의 모양, 동작 등을 정의하는 템플릿을 가져오거나 설정하는 프로퍼티입니다.
- Button, TextBox 등의 비교적 간단한 형태의 컨트롤을 재정의하는데 사용됩니다.
- 내부에서 TemplateBinding과 Binding을 사용할 수 있습니다.
- Custom Control 만들기 Part1 (tistory.com), Custom Control 만들기 Part2 (tistory.com), Custom Control 만들기 Part3 - Packman slider (tistory.com), Custom Control Part4 (tistory.com) 를 참고하셔도 좋습니다.
- ItemTemplate
- ItemsControl을 기본으로 하는 컨트롤들의 아이템 내용을 표시하는데 사용되는 템플릿을 가져오거나 설정하는 프로퍼티입니다.
- ListBox, ComboBox, ItemsControl, ListView 등의 컨트롤에서 사용할 수 있습니다.
- 내부에서 Binidng만 사용할 수 있습니다.
- ItemsPanelTemplate
- ItemsControl을 기본으로 하는 컨트롤들의 아이템 출력 레이아웃을 가져오거나 설정하는 프로퍼티 입니다.
- ListBox, ComboBox, ItemsControl, ListView 등의 컨트롤에서 사용할 수 있습니다.
- HeaderTemplate
- HeaderedContentControl의 Header 부분의 내용을 표시하는데 사용되는 템플릿을 가져오거나 설정하는 프로퍼티입니다.
- TabControl 컨트롤에서 사용할 수 있습니다.
- ContentTemplate
- ContentControl의 Content 부분의 내용을 표시하는데 사용되는 템플릿을 가져오거나 설정하는 프로퍼티입니다.
- ConttentControl 컨트롤에서 사용할 수 있습니다.
Data
- DataTemplate
- 단일 데이터 모델을 유연하게 정의할 수 있는 템플릿을 생성할 때 사용합니다.
- ListBox, ComboBox, ItemsControl, ListView 등의 컨트롤에서 사용할 수 있습니다.
- HierarchicalDataTemplate
- 계층적 데이터 모델을 유연하게 정의할 수 있는 템플릿을 생성할 때 사용합니다.
- TreeView 컨트롤에서 사용할 수 있습니다.
2. 기존 컨트롤의 ControlTemplate 편집하기
Button 컨트롤을 하나 추가한 후 Document Outline에서 마우스 오른쪽 -> Edit Template -> Edit a Copy...
스타일 이름을 RoundButtonStyle로 변경합니다.
아래 리소스가 Button 컨트롤를 구성하는 Xaml 코드 입니다.
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<Style x:Key="RoundButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
3. ControlTemplate 구조
- Style에서 사용할 리소스들
- Style 본체
- Setter 기본 값
- Setter Template
- ControlTemplate 본체
- Border 컨트롤 메인 테두리
- ContentPresenter 컨트롤의 메인 컨텐츠
- Triggers
- Border 컨트롤 메인 테두리
- ControlTemplate 본체
4. ControlTemplate를 수정해서 컨트롤의 모양을 변경할 때 주의 사항 및 팁
- x:Name에 PART_로 시작하는 컨트롤들은 Code behind에서 작업을 하기 때문에 삭제하거나 다른 컨트롤로 변경하면 오류가 발생할 수 있습니다.
- ControlTemplate 내부에는 b:Interaction.Triggers 등을 사용할 수 없습니다.
- Style 내부에 여러개의 Setter가 있는데, 컨트롤의 기본값을 정의한다고 생각하시면 됩니다.
- EventTrigger를 사용할 수는 있지만, Storyboard를 실행하는 용도로만 사용이 가능합니다.
- 내부에서 사용하는 컬러 리소스는 ControlTemplate에서 접근할 수 있는 위치에 있어야 합니다.
5. 컨트롤 모양 수정하기
버튼 테두리에 라운드를 주기 위해서는 Border에 CornerRadius를 입력하면 됩니다.
<Border
x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="10"
SnapsToDevicePixels="true">
이번에는 버튼 내부에 스마일을 추가하겠습니다.
<Grid HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" Text="😊" />
<ContentPresenter
x:Name="contentPresenter"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Focusable="False"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
실행화면
6. ControlTemplate를 잘 활용하려면...
오랜 시간동안 삽질을 해야만 원하는 결과를 얻을 수 있습니다.
다음 포스팅도 계속 이어가도록 하고, 소스는 마지막에 올리겠습니다.
'WPF .NET' 카테고리의 다른 글
MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part8-3 Template (0) | 2022.08.08 |
---|---|
MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part8-2 Template (2) | 2022.08.02 |
MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part7 Behavior (3) | 2022.07.13 |
MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part6 Command (0) | 2022.07.05 |
MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part5 Converter (0) | 2022.06.27 |
- Total
- Today
- Yesterday
- Build 2016
- UWP
- #MVVM
- #uwp
- Behavior
- WPF
- #prism
- IOT
- uno-platform
- .net
- .net 5.0
- ef core
- Always Encrypted
- Bot Framework
- kiosk
- MVVM
- #Windows Template Studio
- PRISM
- XAML
- Windows 10
- LINQ
- windows 11
- ComboBox
- Visual Studio 2022
- visual studio 2019
- Microsoft
- dotNETconf
- Cross-platform
- C#
- uno platform
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |