프로그램 개발/WPF: Style&Template

Button

(ㅇㅅㅎ) 2022. 4. 22. 21:10
728x90
반응형

 안녕하세요, 이번 글에서는 Microsoft에서 제공하는 WPF [Button의 스타일 및 템플릿] 예제를 톺아보도록 하겠습니다.

 

 [Button의 스타일 및 템플릿] 페이지에서 제공되는 예제 코드는 처음 접하시는 분들이라면 당황스러울 수도 있는데요. 한번 제대로 보고 나면 별로 어렵지 않은 내용들이니 이 글을 읽으시고 습득해 나가시길 바라겠습니다. 예제의 XAML 코드를 보기 전, 기본적으로 많이 사용되는 Button Style 속성에 대해서 먼저 알아보도록 하겠습니다.

 


 

[기본적인 Button Style 속성]

Border 

 Button의 테두리입니다. 기본 설정 내역에서는 Border라는 것은 존재하지 않으며 BorderBrush와 BorderThickness를 통해서 색과 두께를 설정합니다.

<Button BorderBrush="Black" BorderThickness="2"/>

 

Background

 Button의 배경색을 설정합니다. 값의 경우 정의된 색을 사용하거나 16진수로 사용할 수 있습니다.

<Button Background="AliceBlue"/>

<Button Background="#ffffffff"/>

 

Content 

 Button 안의 내용을 설정합니다. 기본적으로 Text 설정을 하지만 Text 외에도 이미지를 넣을 수도 있습니다.

<Button Content="기본"/>

<Button>
  <Button.Content>
    <Image Source="이미지 소스 주소"/>
  </Button.Content>
</Button>

Content Image 예시

 

Foreground

 Button 내부의 글자색을 설정합니다. 값의 경우 정의된 색을 사용하거나 16진수로 사용할 수 있습니다.

<Button Foreground="Blue"/>

<Button Foreground="#ff0000ff"/>

 

Height 

 Button의 높이를 설정합니다. 기본 설정에는 Height 외에도 MinHeight(최소 높이)와 MaxHeight(최대 높이)가 있습니다.

<Button Height="100"/>

 

HorizontalAlignment

 Button의 가로 정렬 위치를 설정합니다. 기본값은 Stretch이며, 다른 값으로는 Center, Left, Right가 있습니다.

<Button HorizontalAlignment="Left"/>

HorizontalAlignment 예시

 

HorizontalContentAlignment

 Content의 가로 정렬 위치를 설정합니다. 기본값은 Stretch이며, 다른 값으로는 Center, Left, Right가 있습니다.

<Button HorizontalContentAlignment="Right"/>

HorizontalContentAlignmnet 예시

 

Margin

 Button의 외부 여백을 설정합니다.

<Button Margin="10"/>

Margin 예시

 

Padding

 Button의 내부 여백 너비를 설정합니다.

<Button Padding="10"/>

Padding 예시

 

VerticalAlignment

 Button의 세로 정렬 위치를 설정합니다. 기본값은 Stretch이며, 다른 값으로는 Top, Center, Bottom이 있습니다.

<Button VerticalAlignment="Top"/>

VerticalAlignment 예시

 

VerticalContentAlignment

 Content의 세로 정렬 위치를 설정합니다. 기본값은 Stretch이며, 다른 값으로는 Top, Center, Bottom이 있습니다.

<Button VerticalContentAlignment="Bottom"/>

 

VerticalContentAlignment 예시

 

Width 

 Button의 너비를 설정합니다. 기본 설정에는 Width 외에도 MinWidth(최소 너비)와 MaxWidth(최대 너비)가 있습니다.

<Button Width="200"/>

 

 개인적인 생각으로 자주 사용되는 것들에 대해서 정리를 해보았습니다. 이외의 더 자세한 내용을 알고 싶으시면 Button 클래스 페이지에서 찾아보시길 바랍니다!

 

 


 

[예제 Button Style]

Microsoft Button Style 및 Template 예제

 예제의 XAML 코드를 Button에 적용하면 위와 같은 결과가 나옵니다.(가로와 세로 크기의 경우 편의상 제가 수정했습니다.) 이러한 결과에 도달하도록 코드에 있는 순서대로 설명해드리도록 하겠습니다.

<Style TargetType="Button">
  <Setter Property="SnapsToDevicePixels" Value="true" />
  <Setter Property="OverridesDefaultStyle" Value="true" />
  <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
  <Setter Property="MinHeight" Value="23" />
  <Setter Property="MinWidth" Value="75" />
  <Setter Property="Template">
    <Setter.Value>
      ...
    </Setter.Value>
  </Setter>
</Style>

 

SnapsToDevicePixels

 렌더링 하는 동안 이 요소의 렌더링에 디바이스 관련 픽셀 스냅(Pixel Snap)을 사용할지 여부를 결정하는 값을 설정합니다. 픽셀 스냅을 사용하면 값을 True로 설정하고, 그렇지 않으면 False로 설정합니다. (기본값은 False입니다.)

더보기

⭐ 픽셀 스냅(Pixel Snap)을 사용하는 이유

 WPF에서 시스템 DPI 설정에 맞게 자동으로 크기를 조정하게 됩니다. 이러한 조정할 때 가장자리가 흐려지거나 반투명하게 표시되는 문제가 발생하게 됩니다. 이 문제를 해결하기 위해서 픽셀 스냅 기능을 사용하여 객체의 가장자리를 픽셀에 맞추어 고정시키는 기능을 제공합니다. 픽셀 스냅을 사용하면 객체에 작은 단위의 offset을 적용하여 객체의 크기를 장치 픽셀에 맞추거나 일부분을 렌더링 시점에서 제거하여 해결하는 방법입니다. 

 

OverridesDefaultStyle

 테마 스타일 속성을 포함할지 여부를 나타내는 값입니다. 테마 스타일 속성을 사용하지 않으면 True입니다. 테마 스타일 속성을 사용하면(False일 경우) 직접 지정한 속성을 제외한 나머지 부분은 Local Application Style로 설정됩니다. (기본값은 False입니다.)

⭐ Template에 설정을 하지 않으면 아무것도 나오지 않는 것처럼 보일 수 있습니다.

OverridesDefaultStyle 예시

 

FocusVisualStyle

 Button에 키보드 포커스가 있는 경우 Button에 적용되는 스타일을 설정합니다. 키보드의 포커스에서만 적용됩니다. Microsoft Button Style & Template 예시에서는 "ButtonFocusVisual"이라는 키값의 스타일을 정의한 뒤 사용하였습니다.

<Style x:Key="ButtonFocusVisual">
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate>
        <Border>
          <Rectangle Margin="2" StrokeThickness="1" Stroke="#60000000" StrokeDashArray="1 2" />
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

위의 코드에서 Stroke 값만 Red로 변경

 

MinHeight

 Button의 최소 높이 크기를 설정합니다. 설정하는 법은 Height 설정과 동일합니다.

 

MinWidth

 Button의 최소 폭 크기를 설정합니다. 설정하는 법은 Width 설정과 동일합니다.

 


 

[예제 Button Style - Template]

  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Button">
        ...
      </ControlTemplate>
    </Setter.Value>
  </Setter>

 예제에서 사용되는 Template는 ControlTemplate입니다. ControlTemplate는 Control의 외형을 지정해줄 수 있는 Template입니다. 이번에는 기본적인 Button의 형태인 [Button의 기본]과 이벤트에 따라서 외형이 바꾸도록 설정할 수 있는 [Button의 이벤트]로 나누어서 보도록 하겠습니다.

Template에 대해서 좀 더 아시고 싶으신 분은 이 페이지를 참고하시길 바라겠습니다.

 

Button의 기본

 Button의 기본 형태를 보기 위해서는 Template 내부에서 이벤트에 관련된 코드들을 삭제하는 것이 보기도 편하고 이해하기도 쉽습니다. 이벤트와 관련된 코드는 VisualState 부분과 Trigger부분입니다.

<Border TextBlock.Foreground="{TemplateBinding Foreground}" x:Name="Border" CornerRadius="2" BorderThickness="1">
  <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.Background>
    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
      <GradientStop Color="{DynamicResource ControlLightColor}" Offset="0" />
      <GradientStop Color="{DynamicResource ControlMediumColor}" Offset="1" />
    </LinearGradientBrush>
  </Border.Background>
  
	...
    
  <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" />
</Border>

 위의 코드를 살펴보면 기본적인 Button의 형태를 Border와 ContentPresenter를 사용하였습니다.

⭐ Border.BorderBrush와 Border.Background는 Border의 일부분입니다.

 

Border

 Border는 다른 Control의 주위에 테두리, 배경 또는 둘 다를 그립니다. 그래서 Border의 경우 단독으로 사용 가능하지만 내부에 다른 Control을 오직 1개 넣어서 사용할 수도 있습니다. 그리하여 이번 예제에서는 Button의 Content를 표현하기 위해서 사용한 ContentPresenter를 Border가 감싸는 형태로 사용되어있습니다.

⭐ Border 속성

더보기
TextBlock.Foreground
 Border 내부(이 예제에서는 Button의 내부)에서 사용되는 글자색을 설정합니다. Border의 기본 속성에는 Foreground가 없기 때문에 TextBlock.Foreground 형태로 사용되었습니다. 글자색을 직접적으로 설정해도 되지만, TemplateBinding을 사용하여 부모 Control의 속성(여기서는 Button의 Foreground 속성)을 받아들여서 사용합니다.

x:Name
 Control에 이름을 붙이는 것입니다. 이름을 붙이는 것과 동시에 다른 곳에서 사용할 수 있도록 만들어줍니다. 이 예제에서 "Border"라는 이름을 붙이는 이유는 Button의 이벤트에 따라서 Border 값을 변화시키기 위해서입니다. Button에서는 이름을 변경하여 사용해도 무관하나 다른 Control에서는 지정된 이름을 사용해야 하는 경우도 있습니다.

CornerRadius
 모서리의 둥근 정도를 설정합니다.

BorderThickness
 테두리의 두께를 설정합니다.

BorderBrush
 테두리의 색을 설정합니다. 이 예제에서는 LinearGradientBrush를 사용하여 그라데이션 색을 사용하였습니다.

Background
 테두리의 배경색을 설정합니다. 이 예제의 경우 Border의 배경색이 Button의 배경색입니다. BorderBrush와 마찬가지로 LinearGradientBrush를 사용하여 그라데이션 색을 사용하였습니다.

그라데이션 색에 관해서 궁금하신 분은 이 페이지를 참고하시기 바랍니다.

 

ContentPresenter

 ContentPresenter는 모든 유형의 단일 Contet로 이루어진 Control(ContentControl)의 내용을 표시합니다. 이 예제에서는 Butten의 Content 부분을 나타냅니다.

⭐ ContentPresenter 속성

더보기
Margin
 Content의 외부 여백을 설정합니다.

HorizontalAlignment
 Content의 가로 정렬 위치를 설정합니다.

VerticalAlignment
 Content의 세로 정렬 위치를 설정합니다.

RecognizesAccessKey
 ContentPresenter의 스타일에 AccessText가 사용되는지 여부를 설정합니다. 사용될 경우 True이고, 아니면 False입니다.(기본값은 False입니다.)
⭐ AccessText는 Alt 키를 누르면 Control의 Text/Content 속성에 밑줄을 접두사로 사용하여 액세스 키를 정의합니다. 단축키를 사용하여 이벤트를 줄 때 유용하게 사용됩니다.

 

Button의 이벤트

 Button의 이벤트에는 대표적으로 Click, MouseOver, Pressed 등이 존재합니다. 이 예제에서는 이벤트로 MouseOver와 Pressed가 사용되었고 속성으로 Disabled와 IsDefault가 사용되었습니다. 이 예제에서는 VisualStateGroup의 CommonStates를 사용하여 MouseOver, Pressed와 Disabled를 표현하였고 Trigger로 IsDefault를 표현하였습니다. 

⭐ Disabled라는 속성은 Button에서 존재하지 않습니다. 대신 IsEnabled를 이용하여 Disabled 상태로 적용할 수 있습니다. 

<Button IsEnabled="false"/>

 

VisualStateManager

<VisualStateManager.VisualStateGroups>
  <VisualStateGroup x:Name="CommonStates">
    <VisualStateGroup.Transitions>
      <VisualTransition GeneratedDuration="0:0:0.5" />
      <VisualTransition GeneratedDuration="0" To="Pressed" />
    </VisualStateGroup.Transitions>

    <VisualState x:Name="Normal" />

    <VisualState x:Name="MouseOver">
      <Storyboard>...</Storyboard>
    </VisualState>

    <VisualState x:Name="Pressed">
      <Storyboard>...</Storyboard>
    </VisualState>

    <VisualState x:Name="Disabled">
      <Storyboard>...</Storyboard>
    </VisualState>
  </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

 VisualState는 Control의 시각적 상태를 나타냅니다. MouseOver, Pressed와 Disabled는 CommonStates라는 VisualStateGroup에 포함되므로 VisualStateGroup은 CommonStates로 x:Name을 설정합니다. VisualTransition의 경우 GeneratedDuration을 통해서 시간을 설정할 수 있고 To 또는 From으로 특정 VisualState를 설정할 수 있습니다.

⭐ 만약 VisualTransition을 설정하지 않는다면 시간 지연 없이 바로 변화합니다. 그리고 Normal의 경우 Storyboard가 존재하지 않지만 명시해주지 않으면 MouseOver에서 다시 Normal로 바뀌지 않습니다.

 

VisualState 동작

더보기
1. VisualStateManager에 해당 Control의 변경된 상태를 요청합니다.
2. VisualStateManger는 VisualTransition에 정의되어있는 해당 Storyboard를 우선적으로 수행합니다.
3. VisualTransition의 GeneratedDuration으로 설정된 시간이 경과하면 VisualStateManger는 Control의 해당 VisualStateGroup의 현재 상태(Current State) 속성을 업데이트합니다.
4. VisualStateManager는 1에서 요청한 VisualState의 Storyboard를 수행합니다.

 

 VisualState의 Storyboard는 전부 ColorAnimationUsingKeyFrames를 사용하여 색을 변경하는 애니메이션을 사용하였습니다. Storyboard.TargetName으로 애니메이션을 적용할 부분을 고르고 Storyboard.TargetProperty로 변경할 부분을 선택합니다. 모든 예제는 "Border"라는 이름을 가진 Border(테두리)에 대한 동적인 변화입니다. MouseOver를 예로 들어서 설명해보겠습니다.

 

예시 : MouseOver

MouseOver 예시

<VisualState x:Name="MouseOver">
    <Storyboard>
        <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                      Storyboard.TargetName="Border">
            <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ControlMouseOverColor}" />
        </ColorAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

 Storyboard의 내용을 한글로 풀어보면 ["Border"라는 이름을 가진 것의 Background 중 LinearGradientBrush의 GradientStop 묶음 중 1번(0번부터 시작)에 해당하는 색을 EasingColorKeyFrame에 있는 KeyTime 만큼의 시간을 걸려서 "ControlMouseOverColor"로 바꾸는 것]입니다. 이렇게 Storyboard를 구성하기 위해선 우선적으로 "Border"라는 이름을 가진 Control이 존재해야 하고, 이 Control에 Background가 존재해야 합니다. 그리고 그 Background가 GradientStop 묶음으로 1번이 존재해야 합니다.

 

 

Trigger

<ControlTemplate.Triggers>
  <Trigger Property="IsDefault" Value="true">
    <Setter TargetName="Border" Property="BorderBrush">
      <Setter.Value>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
          <GradientBrush.GradientStops>
            <GradientStopCollection>
              <GradientStop Color="{DynamicResource DefaultBorderBrushLightBrush}" Offset="0.0" />
              <GradientStop Color="{DynamicResource DefaultBorderBrushDarkColor}" Offset="1.0" />
            </GradientStopCollection>
          </GradientBrush.GradientStops>
        </LinearGradientBrush>
      </Setter.Value>
    </Setter>
  </Trigger>
</ControlTemplate.Triggers>

 Trigger는 어떤 조건이나 이벤트 등이 주어졌을 때 Control의 상태 또는 이벤트 핸들러 등을 호출하는 기능을 의미합니다. 예제의 코드는 IsDefault의 속성이 true일 경우 "Border"의 BorderBrush의 색이 바로 바뀌도록 설정되어있습니다. 

⭐ IsDefault 속성은 프로그램이 시작된 뒤 Enter 키를 눌렀을 때 Click 되도록 하는 속성입니다.

 

 

 예제 코드에서는 시각적인 효과를 주로 사용하였습니다만, 소리를 넣어서 청각적인 효과를 설정할 수도 있습니다.

 


 

전체 코드

더보기
<!-- FocusVisual -->
<Style x:Key="ButtonFocusVisual">
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate>
        <Border>
          <Rectangle Margin="2" StrokeThickness="1" Stroke="#60000000" StrokeDashArray="1 2" />
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!-- Button -->
<Style TargetType="Button">
  <Setter Property="SnapsToDevicePixels"
          Value="true" />
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="FocusVisualStyle"
          Value="{StaticResource ButtonFocusVisual}" />
  <Setter Property="MinHeight"
          Value="23" />
  <Setter Property="MinWidth"
          Value="75" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Button">
        <Border TextBlock.Foreground="{TemplateBinding Foreground}"
                x:Name="Border"
                CornerRadius="2"
                BorderThickness="1">
          <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.Background>
            <LinearGradientBrush EndPoint="0.5,1"
                                 StartPoint="0.5,0">
              <GradientStop Color="{DynamicResource ControlLightColor}"
                            Offset="0" />
              <GradientStop Color="{DynamicResource ControlMediumColor}"
                            Offset="1" />
            </LinearGradientBrush>
          </Border.Background>
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
              <VisualStateGroup.Transitions>
                <VisualTransition GeneratedDuration="0:0:0.5" />
                <VisualTransition GeneratedDuration="0"
                                  To="Pressed" />
              </VisualStateGroup.Transitions>
              <VisualState x:Name="Normal" />
              <VisualState x:Name="MouseOver">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
                      (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                Storyboard.TargetName="Border">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource ControlMouseOverColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Pressed">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
                      (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                Storyboard.TargetName="Border">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource ControlPressedColor}" />
                  </ColorAnimationUsingKeyFrames>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
                      (GradientBrush.GradientStops)[0].(GradientStop.Color)"
                                                Storyboard.TargetName="Border">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource PressedBorderDarkColor}" />
                  </ColorAnimationUsingKeyFrames>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
                      (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                Storyboard.TargetName="Border">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource PressedBorderLightColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Disabled">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
                      (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                Storyboard.TargetName="Border">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource DisabledControlDarkColor}" />
                  </ColorAnimationUsingKeyFrames>
                  <ColorAnimationUsingKeyFrames
                      Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                                                Storyboard.TargetName="Border">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource DisabledForegroundColor}" />
                  </ColorAnimationUsingKeyFrames>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
                      (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                Storyboard.TargetName="Border">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource DisabledBorderDarkColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <ContentPresenter Margin="2"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            RecognizesAccessKey="True" />
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsDefault"
                   Value="true">

            <Setter TargetName="Border"
                    Property="BorderBrush">
              <Setter.Value>
                <LinearGradientBrush StartPoint="0,0"
                                     EndPoint="0,1">
                  <GradientBrush.GradientStops>
                    <GradientStopCollection>
                      <GradientStop Color="{DynamicResource DefaultBorderBrushLightBrush}"
                                    Offset="0.0" />
                      <GradientStop Color="{DynamicResource DefaultBorderBrushDarkColor}"
                                    Offset="1.0" />
                    </GradientStopCollection>
                  </GradientBrush.GradientStops>
                </LinearGradientBrush>

              </Setter.Value>
            </Setter>
          </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>

 


 

이 글의 내용은 아래의 사이트에서 기초합니다.

https://docs.microsoft.com/ko-kr/dotnet/desktop/wpf/controls/button-styles-and-templates?view=netframeworkdesktop-4.8 

 

Button 스타일 및 템플릿 - WPF .NET Framework

Windows Presentation Foundation 단추 컨트롤의 스타일 및 템플릿에 대해 알아봅니다. 컨트롤에 고유한 모양을 지정하도록 ControlTemplate을 수정합니다.

docs.microsoft.com

 

 

반응형

'프로그램 개발 > WPF: Style&Template' 카테고리의 다른 글

Calendar②  (0) 2022.05.04
Calendar①  (0) 2022.05.03
Template  (0) 2022.04.15
Color  (0) 2022.04.08
[wpf] Microsoft Control Style & Template 톺아보기  (0) 2022.04.07