2020년 7월 9일 목요일

WPF - Style


1. 기본 문법

1. Style 기본


1
2
3
4
5
6
7
8
9
10
11
<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="FontSize" Value="12"/>
            <Setter Property="Foreground" Value="#00ff00"/>
        </Style>
    </StackPanel.Resources>
    <TextBlock Text="한국"/>
    <TextBlock Text="한국"/>
    <TextBlock Text="한국"/>
</StackPanel>
cs

TargetType 을 지정하고, Setter 로 타입의 속성을 위처럼 지정함.

위 예시에선 Resources 는 자기 하위에 적용되므로 TextBlock 모두에 적용될 것임.


2. Style 의 Scope


적용되는 대상 기준으로는 가까운 것이 우선적으로 적용됨.

가장 위쪽으론 Application, 가장 아래쪽으론 Control 직하의 Style 이 있음.


1
2
3
4
5
6
7
<TextBlock Text="한국">
    <TextBlock.Style>
        <Style>
            <Setter Property="TextBlock.Foreground" Value="Red"/>
        </Style>
    </TextBlock.Style>
</TextBlock>
cs

위가 Control 직하 Style 임.
TargetType 을 지정하지 않으면 위처럼 클래스의 메소드처럼 표기함.

3. Style 지정


1
2
3
4
5
6
7
8
<Style x:Key="styleBtnOk" TargetType="Button">
    <Setter Property="FontSize" Value="16"/>
    <Setter Property="Foreground" Value="#0000ff"/>
</Style>
    
    ...
    
<Button Content="확인" Style="{StaticResource styleBtnOk}"/>
cs

x:key 로 style 의 이름을 지정함
control 의 style 에 Binding 규칙을 써서 StaticResource 로 Style 의 이름을 써서 연동.


4. Trigger


Trigger 은 동적으로 Style 을 바꾸게 해줌.
단 Style 로 지정된 속성이 아닌 태그 자체에서 지정한 속성이면 안바뀜. 

종류는 5가지가 있음.

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
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
    <TextBlock.Style>
        <Style TargetType="TextBlock">
            <Setter Property="Text" Value="WPF Programming"/>
            <Setter Property="Foreground" Value="Blue"/>
            <Setter Property="FontSize" Value="28"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="Red"/>
                    <Setter Property="FontSize" Value="30"/>
                </Trigger>
                <DataTrigger Binding="{Binding ElementName=chkMail, Path=IsChecked}" Value="True">
                    <Setter Property="Text" Value="Yes"/>
                    <Setter Property="Foreground" Value="Green"/>
                </DataTrigger>
                <EventTrigger RoutedEvent="MouseLeave">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Duration="0:0:0.3"
                                                         Storyboard.TargetProperty="FontSize"
                                                         From="18" To="50"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>
<CheckBox x:Name="chkMail" Content="메일 수신 동의"/>
cs

Trigger 에선 Style 대상의 속성이 Value 의 속성과 같을 때 Setter 가 적용됨
위 예시에선 마우스 올려놓으면 폰트사이즈와 글자색이 바뀜.
ex) <TextBlock FontSize="30"> 이러면 FontSize 는 안바뀜.

DataTrigger 에선 Binding 된 속성이 Path 로 지정한 값과 같은 경우 Value 의 값이 참이 됨.
위 예시에선 chkMail 이 IsChecked 면 True 란 이야기.
True 의 경우 이하의 조건을 동적으로 바꾸게함.

EventTrigger 에선 RoutedEvent 가 실행 시 Setter 가 적용됨.
위 예시에선 폰트 사이즈가 동적으로 바뀜.


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
<CheckBox x:Name="chkInfo" Content="개인정보 활용 동의"/>
<CheckBox x:Name="chkEmail" Content="이메일 수신 동의"/>
<Button Content="버튼" Width="100">
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="IsEnabled" Value="False"/>
            <Style.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsEnabled" Value="True"/>
                        <Condition Property="Content" Value="버튼"/>
                    </MultiTrigger.Conditions>
                    <MultiTrigger.Setters>
                        <Setter Property="Background"  Value="#ff0000"/>
                    </MultiTrigger.Setters>
                </MultiTrigger>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding ElementName=chkInfo, Path=IsChecked}" Value="True"/>
                        <Condition Binding="{Binding ElementName=chkEmail, Path=IsChecked}" Value="True"/>
                    </MultiDataTrigger.Conditions>
                    <Setter Property="IsEnabled" Value="True"/>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>
cs

MultiTrigger 는 그냥 Trigger 의 조건이 여러개의 버전임.
위 예시에선 button 이 활성화되고 Content 가 '버튼' 이면 배경색이 빨개짐.

MultiDataTrigger 는 DataTrigger 의 조건이 여러개의 버전임.
위 예시에선 체크박스 두개가 체크되어 있으면 버튼이 활성화됨.
    
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
32
33
34
35
36
37
38
<Border Background="LightBlue" Width="150" Height="150" BorderBrush="Blue">
    <Border.Style>
        <Style TargetType="Border">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ThicknessAnimation Duration="0:0:0.5" Storyboard.TargetProperty="BorderThickness"
                                                            To="3"/>
                                <DoubleAnimation Duration="0:0:0.2" BeginTime="0:0:0.5"
                                                         Storyboard.TargetProperty="Width"
                                                         To="300"/>
                                <DoubleAnimation Duration="0:0:0.2" BeginTime="0:0:0.7"
                                                         Storyboard.TargetProperty="Height"
                                                         To="300"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                    <Trigger.ExitActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ThicknessAnimation Duration="0:0:0.5" Storyboard.TargetProperty="BorderThickness"
                                                            To="0"/>
                                <DoubleAnimation Duration="0:0:0.2" BeginTime="0:0:0.5"
                                                         Storyboard.TargetProperty="Width"
                                                         To="150"/>
                                <DoubleAnimation Duration="0:0:0.2" BeginTime="0:0:0.7"
                                                         Storyboard.TargetProperty="Height"
                                                         To="150"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.ExitActions>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
</Border>
cs

Trigger, DataTrigger, EventTrigger 모두에 적용되는 부분.
조건에 따라 적용될 때와 적용이 취소 될 때를 세트로 적용가능함


ContentPresenter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<TabControl.Resources>
    <Style TargetType="{x:Type TabItem}">
        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <DataTemplate>
                    <ContentPresenter Content="{TemplateBinding Content}">
                        <ContentPresenter.LayoutTransform>
                            <RotateTransform Angle="90"/>
                        </ContentPresenter.LayoutTransform>
                    </ContentPresenter>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</TabControl.Resources>
cs

 위를 실행하면 TabControl 의 Header 의 글자가 돌려서 보임.
 




댓글 없음:

댓글 쓰기

List