티스토리 뷰

반응형

2022.12.14 - [WPF .NET] - Trigger를 사용해서 동적 UI 구성하기 Part1 - Overview

1. 새로운 ItemTemplate

이전 보다 좀더 여러가지 효과를 추가해 보았습니다.

  • DropShadowEffect라는 효과로 그림자 효과를 추가할 수 있습니다.
  • LayoutTransform의 ScaleX, ScaleY를 조정하면 확대/축소 할 수 있습니다.
<DataTemplate x:Key="ListBoxItemTemplate1">
    <Border CornerRadius="5">
        <Border.Style>
            <Style TargetType="Border">
                <Setter Property="Background" Value="#FFFFFF" />
                <Setter Property="BorderThickness" Value="1" />
                <Setter Property="BorderBrush" Value="#DDDDDD" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True">
                        <Setter Property="Effect">
                            <Setter.Value>
                                <DropShadowEffect
                                    BlurRadius="10"
                                    Opacity="0.8"
                                    ShadowDepth="-5"
                                    Color="#0F62D8" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="LayoutTransform">
                            <Setter.Value>
                                <ScaleTransform ScaleX="1.3" ScaleY="1.3" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="BorderBrush" Value="#0F62D8" />
                        <Setter Property="BorderThickness" Value="2" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
        <TextBlock
            Margin="4"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Text="{Binding Name}"
            TextAlignment="Center" />
    </Border>
</DataTemplate>

실행

2. ListBoxItem의 Background에 색 변경하기

두번째 ListBox를 아래와 같이 Edit a Copy... 메뉴를 선택합니다.

아래 XAML 코드를 보면 ControlTemplate.Triggers에 여러개의 MKultiTrigger들에 의해서 Bd라는 이름의 Border의 배경색과 테두리색을 변경하는 것을 볼 수 있습니다. 그래서, Trigger에서 사용하는 컬러 리소스의 색을 변경하거나, Trigger를 새로 정의를 해야지만 배경색을 변경할 수 있습니다.

 

이전 회차에서 작성한 트리거는 Style.Trigger로 ControlTemplate.Trigger보다 먼저 적용이되기 때문에 색이 지워지는 것으로 판단됩니다.

 

여기서는 Item.SelectedActive.Background의 색을 Red로 변경했습니다.

<!--  Edit a Copy...를 눌러서 뽑아낸 XAML 코드들  -->
<Style x:Key="FocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle
                    Margin="2"
                    SnapsToDevicePixels="true"
                    Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
                    StrokeDashArray="1 2"
                    StrokeThickness="1" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<!--  백라운드 컬러를 쉽게 변경하려면 아래 컬러를 변경하면 됩니다.  -->
<SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA" />
<SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da" />
<!--<SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3D26A0DA" />-->
<SolidColorBrush x:Key="Item.SelectedActive.Background" Color="Red" />
<SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA" />
<SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA" />
<SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA" />
<Style x:Key="ListBoxItemContainerStyle1" TargetType="{x:Type ListBoxItem}">
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="Padding" Value="4,1" />
    <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
    <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="BorderBrush" Value="Transparent" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Border
                    x:Name="Bd"
                    Padding="{TemplateBinding Padding}"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    SnapsToDevicePixels="true">
                    <ContentPresenter
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                </Border>
                <ControlTemplate.Triggers>
                    <!--  아래 트리거들에 의해서 백그라운드 색이 덥어지기 때문에 효과가 없습니다.  -->
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.MouseOver.Background}" />
                        <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.MouseOver.Border}" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelectionActive" Value="False" />
                            <Condition Property="IsSelected" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedInactive.Background}" />
                        <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedInactive.Border}" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelectionActive" Value="True" />
                            <Condition Property="IsSelected" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedActive.Background}" />
                        <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedActive.Border}" />
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="Bd" Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

실행

3. Trigger 사용이 어려운데요?

  • Condition이나 Setter에 인텔리센스 지원 미흡으로 정확한 이름을 입력하기가 어려움
    • 이 부분은 다른 Trigger를 많이 보고, 익히는 방법이 제일 빠른 것 같습니다. Selector.IsSelectionActive, TextElement.Foreground 같은 프로퍼티들은 쉽게 알 수 없는 녀석들이기 때문입니다.
  • 비교할 값이나 설정할 값을 입력하기도 어려움
  • 처음부터 쉬운것은 없습니다~ 꾸준히 사용하시면 점점 익숙해지니 조급할 필요는 없는 것 같습니다.

4. 소스

WpfTest/TriggerSample2 at master · kaki104/WpfTest (github.com)

 

GitHub - kaki104/WpfTest

Contribute to kaki104/WpfTest development by creating an account on GitHub.

github.com

 

 

 

반응형
댓글