안녕하세요, 이번 글에서는 Microsoft에서 제공하는 WPF [Expander의 스타일 및 템플릿] 예제를 톺아보도록 하겠습니다.
Expander
Expander는 Content를 표시하는 축소 가능한 창이 포함된 Header를 표시하는 Control를 나타냅니다.
[ Expander 속성 ]
ExpandDirection
Expander Content 창이 열리는 방향을 설정합니다. 기본값은 Down이며, 다른 값으로 Left, Right, Up이 있습니다.
<Expander ExpandDirection="Right" />
IsExpanded
Expander Content 창이 표시되는지 여부를 설정합니다. Content 창이 확장되면 true이고, 그렇지 않으면 false(기본값)입니다.
<Expander IsExpanded="True" />
[ Expander Style ]
예제의 XAML 코드를 Expander에 적용하면 위와 같은 결과가 나옵니다. 이러한 결과에 도달하도록 코드 순서로 속성을 살펴보면 다음과 같습니다.
Expander 속성
<Style TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Grid>
...
<Border x:Name="Border" ...>
...
<Grid>
...
<ToggleButton ...>
...
</ToggleButton>
<ContentPresenter ... />
</Grid>
</Border>
<Border x:Name="Content" ...>
...
<ContentPresenter Margin="4" />
</Border>
</Grid>
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Template
Control의 템플릿을 설정합니다. 예제에서 사용되는 Template는 Control의 외형을 지정해줄 수 있는 ControlTemplate입니다.
👀 Template에 대해서 좀 더 아시고 싶으신 분은 이 페이지를 참고하시길 바랍니다.
Expander Style 구성
Expander Style은 Grid 내부에 ToggleButton과 ContentPresenter(Expander의 Header)로 구성하였습니다. 그리고 Border를 사용하여 ContentPresenter(Expander의 Content)를 구성하였습니다.
Grid
열 및 행으로 구성되는 유연한 모눈 영역을 정의합니다.
⭐ Grid 속성
바깥쪽
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition x:Name="ContentRow" Height="0" />
</Grid.RowDefinitions>
...
</Grid>
안쪽
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
...
</Grid>
RowDefinitions
Grid에 RowDefinition을 사용하여 RowDefinitionCollection(RowDefinition 개체의 순서가 지정된 컬렉션)을 설정합니다.
RowDefinition
Grid 요소에 적용되는 행 별 속성을 정의합니다. Height로 높이를 숫자 값, 'Auto' 또는 '*'(기본값)로 설정할 수 있습니다.
ColumnDefinitions
Grid에 ColumnDefinition을 사용하여 ColumnDefinitionCollection(ColumnDefinition 개체의 순서가 지정된 컬렉션)을 설정합니다.
ColumnDefinition
Grid 요소에 적용되는 열 별 속성을 정의합니다. Width로 너비를 숫자 값, 'Auto' 또는 '*'(기본값)로 설정할 수 있습니다.
Border(Border, Content)
다른 요소의 주위에 윤곽선, 배경 또는 둘 다를 그립니다.
⭐ Border 속성
x:Name="Border"
<Border x:Name="Border" Grid.Row="0" BorderThickness="1" CornerRadius="2,2,0,0">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="{DynamicResource BorderLightColor}" Offset="0" />
<GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1" />
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}" Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
...
</Border>
x:Name="Content"
<Border x:Name="Content" Grid.Row="1" BorderThickness="1,0,1,1" CornerRadius="0,0,2,2">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="{DynamicResource ContentAreaColorDark}" />
</Border.Background>
...
</Border>
x:Name
Border에 이름을 설정합니다. 이름을 붙이는 것과 동시에 다른 곳에서 사용할 수 있도록 만들어줍니다.
Grid.Row
표시할 Grid(Parent)의 행을 설정합니다.
BorderThickness
Border의 윤곽선 두께를 설정합니다.
CornerRadius
모퉁이가 둥근 정도를 설정합니다.
BorderBrush
Border의 윤곽선 색을 설정합니다.
Background
Border의 배경색을 설정합니다.
🌟 "Content"에서는 BorderBrush와 Background를 SolidColorBrush를 사용하여 미리 정의한 색으로 설정했습니다.
🌟 "Border"에서는 BorderBrush와 Background를 LinearGradientBrush를 사용하여 그라데이션 색으로 설정했습니다.
👀 그라데이션 색에 관해서 궁금하신 분은 이 페이지를 참고하시길 바랍니다.
ToggleButton
상태를 전환할 수 있는 Control입니다.
⭐ ToggleButton 속성
<ToggleButton OverridesDefaultStyle="True" Template="{StaticResource ExpanderToggleButton}"
IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
<ToggleButton.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}" Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}" Offset="1" />
</LinearGradientBrush>
</ToggleButton.Background>
</ToggleButton>
OverridesDefaultStyle
ToggleButton가 테마 Style을 포함할지 여부를 설정합니다. 속성을 사용하지 않으면 true이고, 사용하면 false입니다.
Template
Control의 템플릿을 설정합니다. 예제에서 사용되는 Template는 Control의 외형을 지정해줄 수 있는 ControlTemplate입니다. 예제에서는 미리 정의한 "ExpanderToggleButton"을 사용하였습니다.
IsChecked
ToggleButton이 선택된 상태인지 여부를 설정합니다. 선택되어 있으면 true이고, 선택되어 있지 않으면 false(기본값)입니다. 예제에서는 Binding을 사용하여 TemplateParent의 IsExpanded로 설정했습니다.
Background
ToggleButton의 배경색을 설정합니다. 예제에서는 LinearGradientBrush를 사용하여 그라데이션 색으로 설정했습니다.
👀 그라데이션 색에 관해서 궁금하신 분은 이 페이지를 참고하시길 바랍니다.
ContentPresenter
모든 유형의 단일 Content로 이루어진 Control을 나타냅니다.
⭐ ContentPresenter 속성
Grid.Row="0"
<ContentPresenter Grid.Column="1" Margin="4" ContentSource="Header" RecognizesAccessKey="True" />
Grid.Row="1"
<ContentPresenter Margin="4" />
Grid.Column
표시할 Grid(Parent)의 열을 설정합니다.
Margin
ContentPresenter의 바깥쪽 여백을 설정합니다.
ContentSource
별칭을 자동으로 지정할 때 사용할 기본 이름을 설정합니다. 예제에서는 Expander의 "Header" 값으로 설정했습니다.
RecognizesAccessKey
ContentPresenter의 Style에 AccessText가 사용되는지 여부를 설정합니다. AccessText가 사용되면 true이고, 그렇지 않으면 false(기본값)입니다.
🌟 AccessText는 Alt 키를 누르면 Control의 Text/Content 속성에 밑줄을 접두사로 사용하여 액세스 키를 정의합니다. 단축키를 사용하여 이벤트를 줄 때 유용하게 사용됩니다.
Expander 이벤트
예제에서는 Expander 이벤트로 Disabled 변화를 VisualStateManager와 IsExpanded 변화를 Triggers로 표현하였습니다.
VisualStateManager
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
VisualState는 Control의 시각적 상태를 나타냅니다. 예제의 이벤트에서 시각적 변화를 주기 위해서 VisualStateGroup의 x:Name을 CommonStates로 설정했습니다.
⭐ Expander는 5개(CommonStates, FocusStates, ExpnsionStates, ExpandDirectionStates, ValidationStates)의 VisualStateGroup을 가지고 있습니다.
CommonStates
Disabled
Storyboard의 내용을 풀어보면 ["Border"라는 이름을 가진 Control의 Background를 DisabledControlDarkColor 그리고 BorderBrush를 DisabledBorderLightColor로 바꾸는 것]입니다.
ColorAnimationUsingKeyFrames
지정된 Duration에 대해 KeyFrames 집합을 따라 Color 속성 값에 애니메이션 효과를 줍니다.
Triggers
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ContentRow" Property="Height" Value="{Binding Height, ElementName=Content}" />
</Trigger>
</ControlTemplate.Triggers>
Trigger는 어떤 조건이나 이벤트 등이 주어졌을 때 Control의 상태 또는 이벤트 핸들러 등을 호출하는 기능을 의미합니다. 예제의 코드는 IsExpanded의 값이 true일 경우 ContentRow의 Height값을 Binding을 사용하여 Content의 Height로 설정합니다.
[ ExpanderToggleButton ]
예제에 사용된 ExpanderToggleButton은 ToggleButton 부분을 ControlTemplate로 미리 정의해둔 것입니다.
ExpanderToggleButton 구성
<ControlTemplate x:Key="ExpanderToggleButton" TargetType="{x:Type ToggleButton}">
<Border x:Name="Border" ...>
...
<Grid>
<Path x:Name="CollapsedArrow" ...>
...
</Path>
<Path x:Name="ExpandededArrow" ...>
...
</Path>
</Grid>
</Border>
</ControlTemplate>
ExpanderToggleButton은 위의 이미지처럼 Grid 내부에 Path 2개가 구성되어있습니다.
Border(Border)
다른 요소의 주위에 윤곽선, 배경 또는 둘 다를 그립니다.
⭐ Border 속성
<Border x:Name="Border" CornerRadius="2,0,0,0" BorderThickness="0,0,1,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}" Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
...
</Border>
x:Name
Border에 이름을 설정합니다. 이름을 붙이는 것과 동시에 다른 곳에서 사용할 수 있도록 만들어줍니다.
CornerRadius
모퉁이가 둥근 정도를 설정합니다.
BorderThickness
Border의 윤곽선 두께를 설정합니다.
Background
Border의 배경색을 설정합니다. 예제에서는 LinearGradientBrush를 사용하여 그라데이션 색으로 설정했습니다.
BorderBrush
Border의 윤곽선 색을 설정합니다. 예제에서는 LinearGradientBrush를 사용하여 그라데이션 색으로 설정했습니다.
👀 그라데이션 색에 관해서 궁금하신 분은 이 페이지를 참고하시길 바랍니다.
Grid
열 및 행으로 구성되는 유연한 모눈 영역을 정의합니다.
Path(CollapsedArrow, ExpandededArrow)
일련의 연결된 선 및 곡선을 그립니다.
⭐ Path 속성
CollapsedArrow
<Path x:Name="CollapsedArrow" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
ExpandededArrow
<Path x:Name="ExpandededArrow" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed" Data="M 0 4 L 4 0 L 8 4 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
x:Name
Path에 이름을 설정합니다. 이름을 붙이는 것과 동시에 다른 곳에서 사용할 수 있도록 만들어줍니다.
HorizontalAlignment
Path의 가로 정렬 위치를 설정합니다. 기본값은 Stretch이며, 다른 값으로는 Left, Center, Right가 있습니다.
VerticalAlignment
Path의 세로 정렬 위치를 설정합니다. 기본값은 Stretch이며, 다른 값으로는 Top, Center, Bottom이 있습니다.
Visibility
Path의 표시 유형을 설정합니다.
Data
그릴 모양을 지정하는 Geometry를 설정합니다.
Fill
도형의 내부 색을 설정합니다. 예제에서는 SolidColorBrush를 사용하여 GlyphColor로 설정했습니다.
👀 Path에 대해서 좀 더 아시고 싶으신 분은 이 페이지를 참고하시길 바랍니다.
ExpanderToggleButton 이벤트
예제에서는 ExpanderToggleButton의 이벤트로 MouseOver, Pressed, Disabled와 Checked 변화를 VisualStateManger로 표현하였습니다.
VisualStateManager
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
...
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
...
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
VisualState는 Control의 시각적 상태를 나타냅니다. 예제의 이벤트에서 시각적 변화를 주기 위해서 VisualStateGroup의 x:Name을 CommonStates와 CheckStates로 설정했습니다.
CommonStates
<VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="MouseOver"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ControlMouseOverColor}" /> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ControlPressedColor}" /> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledControlDarkColor}" /> </ColorAnimationUsingKeyFrames> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Border.BorderBrush).(GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledBorderLightColor}" /> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup>
MouseOver
Storyboard의 내용을 풀어보면 ["Border"라는 이름을 가진 Control의 Background를 ControlMouseOverColor로 바꾸는 것]입니다.
Pressed
Storyboard의 내용을 풀어보면 ["Border"라는 이름을 가진 Control의 Background를 ControlPressedColor로 바꾸는 것]입니다.
Disabled
Stoyboard의 내용을 풀어보면 ["Border"라는 이름을 가진 Control의 Background를 DisabledControlDarkColor 그리고 BorderBrush를 DisabledBorderLightColor로 바꾸는 것]입니다.
🌟 Normal의 경우 Storyboard가 존재하지 않지만 명시해주지 않으면 상태가 Normal로 변할 때 외형이 바뀌지 않습니다.
ColorAnimationUsingKeyFrames
KeyFrames 집합을 따라 Color 속성 값에 EasingColorKeyFrame의 애니메이션 효과를 줍니다.
CheckStates
<VisualStateGroup x:Name="CheckStates"> <VisualState x:Name="Checked"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="CollapsedArrow"> <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ExpandededArrow"> <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Unchecked" /> <VisualState x:Name="Indeterminate" /> </VisualStateGroup>
Checked
Storyboard의 내용을 풀어보면 ["CollapsedArrow"라는 이름을 가진 Control의 Visibility를 Hidden 그리고 ExpandededArrow의 Visibility를 Visible로 바꾸는 것]입니다.
ObjectAnimationUsingKeyFrames
지정된 Object에 대해 KeyFrames 집합을 따라 Duration 속성 값에 애니메이션 효과를 줍니다.
전체 코드
<ControlTemplate x:Key="ExpanderToggleButton"
TargetType="{x:Type ToggleButton}">
<Border x:Name="Border"
CornerRadius="2,0,0,0"
BorderThickness="0,0,1,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="CollapsedArrow">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="ExpandededArrow">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Path x:Name="CollapsedArrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
<Path x:Name="ExpandededArrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="Collapsed"
Data="M 0 4 L 4 0 L 8 4 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
</Grid>
</Border>
</ControlTemplate>
<Style TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition x:Name="ContentRow"
Height="0" />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border"
Grid.Row="0"
BorderThickness="1"
CornerRadius="2,2,0,0">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1" />
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ToggleButton OverridesDefaultStyle="True"
Template="{StaticResource ExpanderToggleButton}"
IsChecked="{Binding IsExpanded, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}">
<ToggleButton.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</ToggleButton.Background>
</ToggleButton>
<ContentPresenter Grid.Column="1"
Margin="4"
ContentSource="Header"
RecognizesAccessKey="True" />
</Grid>
</Border>
<Border x:Name="Content"
Grid.Row="1"
BorderThickness="1,0,1,1"
CornerRadius="0,0,2,2">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="{DynamicResource ContentAreaColorDark}" />
</Border.Background>
<ContentPresenter Margin="4" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded"
Value="True">
<Setter TargetName="ContentRow"
Property="Height"
Value="{Binding Height, ElementName=Content}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
이 글의 내용은 아래의 사이트에서 기초합니다.
'프로그램 개발 > WPF: Style&Template' 카테고리의 다른 글
Frame② (0) | 2022.05.26 |
---|---|
Frame① (0) | 2022.05.25 |
DocumentViewer (0) | 2022.05.20 |
DatePicker② (0) | 2022.05.19 |
DatePicker① (0) | 2022.05.18 |