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

CheckBox

(ㅇㅅㅎ) 2022. 5. 5. 21:28
728x90
반응형

 

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

 

 

 

[CheckBox]

CheckBox

 CheckBox는 사용자가 선택하거나 선택을 취소할 수 있는 Control을 나타냅니다.

 

 


 

 

[CheckBox 기본 속성]

Background

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

<CheckBox Background="AliceBlue" />

Background

 

 

BorderBrush

 CheckBox의 테두리 색을 설정합니다.

<CheckBox BorderBrush="#FFFF0000" />

BorderBrush

 

 

BorderThickness

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

<CheckBox BorderThickness="3" />

BorderThickness

 

 

Content

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

<CheckBox Content="기본" />

<CheckBox>
    <CheckBox.Content>
        <Image Source="pack://application:,,,/ㅇㅅㅎ.png" />
    </CheckBox.Content>
</CheckBox>

Content

 

 

Height

 CheckBox의 높이를 설정합니다. 여기서 높이는 Check 마크 부분(Bullet 부분)이 아닌 Control 전체의 높이를 의미합니다.

<CheckBox Height="50" />

Height

 

 

IsChecked

 ToggleButton이 선택된 상태인지 여부를 설정합니다.

<CheckBox IsChecked="True" />

IsChecked False와 True

 

 

IsThreeState

 Control이 2~3가지 상태를 지원 여부를 설정합니다. 기본값은 False입니다.

<CheckBox IsThreeState="True" />

IsThreeState

 

 

LayoutTransform

 Layout을 수행할 때 이 요소에 적용해야 하는 그래픽 변환을 가져오거나 설정합니다. CheckBox에서는 Layout의 ScaleTransform으로 내부 크기를 설정할 수 있습니다.

⭐ Width와 height로는 Checkbox의 Bullet 부분의 크기를 설정할 수 없습니다.

<CheckBox>
    <CheckBox.LayoutTransform>
        <ScaleTransform ScaleX="2" ScaleY="2"/>
    </CheckBox.LayoutTransform>
</CheckBox>

LayoutTransform

 

 

Width

 Control의 너비를 설정합니다.

<CheckBox Width="100" />

 

 


 

 

[CheckBox Style]

 예제의 XAML 코드를 CheckBox에 적용하면 위와 같은 결과가 나옵니다. 이러한 결과에 도달하도록 코드 순서로 속성을 살펴보면 다음과 같습니다.

<Style x:Key="{x:Type CheckBox}" TargetType="{x:Type CheckBox}">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="OverridesDefaultStyle" Value="true" />
    <Setter Property="FocusVisualStyle" Value="{DynamicResource CheckBoxFocusVisual}" />
    <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에 설정을 하지 않으면 아무것도 나오지 않는 것처럼 보일 수 있습니다.

 

 

FocusVisualStyle

 CheckBox에 키보드 포커스가 있는 경우 CheckBox에 적용되는 스타일을 설정합니다. 키보드의 포커스에서만 적용됩니다. 예제에서는 "CheckBoxFocusVisual"이라는 미리 정의되어있는 키값을 사용하였습니다.

⭐ 예제의 실수인지는 몰라도 "CheckBoxFocusVisual"이라는 ControlTemplate을 찾을 수 없습니다. 즉, 이 부분이 없어도 동작은 달라지지 않습니다.

 

 

Template

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type CheckBox}">
            <BulletDecorator Background="Transparent">
                <BulletDecorator.Bullet>
                    <Border x:Name="Border" Width="13" Height="13" CornerRadius="0" BorderThickness="1">
                        <Border.BorderBrush> ... </Border.BorderBrush>
                        
                        <Border.Background> ... </Border.Background>

                        <Grid>
                            <Path Visibility="Collapsed" Width="7" Height="7" x:Name="CheckMark" SnapsToDevicePixels="False" StrokeThickness="2"
                                  Data="M 0 0 L 7 7 M 0 7 L 7 0">
                                <Path.Stroke>
                                    <SolidColorBrush Color="{DynamicResource GlyphColor}" />
                                </Path.Stroke>
                            </Path>

                            <Path Visibility="Collapsed" Width="7" Height="7" x:Name="InderminateMark" SnapsToDevicePixels="False" StrokeThickness="2"
                                  Data="M 0 7 L 7 0">
                                <Path.Stroke>
                                    <SolidColorBrush Color="{DynamicResource GlyphColor}" />
                                </Path.Stroke>
                            </Path>
                        </Grid>
                    </Border>
                </BulletDecorator.Bullet>
                
                <VisualStateManager.VisualStateGroups>
                    ...
                </VisualStateManager.VisualStateGroups>
                
                <ContentPresenter Margin="4, 0, 0, 0" VerticalAlignment="Center" HorizontalAlignment="Left" RecognizesAccessKey="True" />
            </BulletDecorator>
        </ControlTemplate>
    </Setter.Value>
</Setter>

 위의 코드는 이벤트 부분(VisualStateManager 부분)을 제외한 Template 코드입니다. 예제에서 사용되는 Template는 Control의 외형을 지정해줄 수 있는 ControlTemplate입니다.  Template 내부 코드를 보기 전, CheckBox의 구성에 대해서 알아보도록 하겠습니다.

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

 

 

CheckBox 구성

 예제의 CheckBox 구성을 이미지로 나타내어보면 위와 같이 BulletDecorator가 BulletDecorator.Bullet와 ContentPresenter를 감싼 모습입니다.

 

BulletDecorator

 BulletDecorator는 두 개의 Content 속성 Bullet과 Child가 있습니다. Bullet은 글머리 기호로 사용할 개체 그리고 Child는 글머리 기호를 시각적으로 설정합니다.

 

ContentPresenter

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

⭐ ContentPresenter 속성

더보기
Margin
 ContentPresenter의 외부 여백을 설정합니다. 값을 1개(상하좌우 동일), 2개(좌우, 상하), 4개(좌, 상, 우, 하)로 나누어서 설정가능합니다.

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

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

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

 

Border

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

⭐ Border 속성

더보기
x:Name
 Border에 이름을 붙이는 것입니다. 이름을 붙이는 것과 동시에 다른 곳에서 사용할 수 있도록 만들어줍니다.

Width
 Border의 너비를 설정합니다.

Height
 Border의 높이를 설정합니다.

CornerRadius
 모서리의 둥근 정도를 설정합니다. 하지만 예제에서는 값이 0이기 때문에 속성을 사용하지 않아도 상관없습니다.

BorderThickness
 Border의 윤곽선 두께를 설정합니다.

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

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

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

 

Grid

 열 및 행으로 구성되는 모눈 영역을 정의하는 Control입니다. 예제에서는 Border 내부에 2가지 Path를 구성하기 위하여 사용되었습니다.

 

Path

 일련의 연결된 선 및 곡선을 그립니다.

⭐ Path 속성

더보기
Visibility
 Path의 표시 유형을 설정합니다. 기본 값은 Visible이며 다른 값으로는 Collapsed와 Hidden이 있습니다.

Width
 Path의 너비를 설정합니다.

Height
 Path의 높이를 설정합니다.

x:Name
 Path에 이름을 설정합니다. 이름을 붙이는 것과 동시에 다른 곳에서 사용할 수 있도록 만들어줍니다.

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

StrokeThickness
 Path의 윤곽선 두께를 설정합니다.

Data
 그릴 모양을 지정하는 Geometry를 설정합니다.

Stroke
 Path의 윤곽선 색을 설정합니다. 예제에서는 SolidColorBrush를 사용하여 미리 정의한 색을 설정하였습니다.

⭐ Path에 관해서는 이 페이지를 참고하시길 바랍니다.

 

 

CheckBox의 이벤트

 예제에서는 CheckBox의 이벤트로 MouseOver, Pressed, Checked와 Indeterminate 변화를 VisualStateManager로 표현하였습니다. 

 

VisualStateManager

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
        ... 
    </VisualStateGroup>
    <VisualStateGroup x:Name="CheckStates">
        ...
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

 VisualState는 Control의 시각적 상태를 나타냅니다. 예제의 이벤트에서 시각적 변화를 주기 위해서 VisualStateGroup의 x:Name을 각각 CommonStates(MouseOver, Pressed)와 CheckStates(Checked, Indeterminate)로 설정했습니다.

⭐ CheckBox는 4개(CommonStates, FocusStates, CheckStates, ValidationStates)의 VisualStateGroup을 가지고 있습니다.

 

⭐ VisualState 동작

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

 

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>
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Border.BorderBrush).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
                <EasingColorKeyFrame KeyTime="0" Value="{StaticResource PressedBorderDarkColor}" />
            </ColorAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Border.BorderBrush).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                <EasingColorKeyFrame KeyTime="0" Value="{StaticResource PressedBorderLightColor}" />
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
    <VisualState x:Name="Disabled" />
</VisualStateGroup>
MouseOver
 Storyboard의 내용을 풀어보면 ["Border"라는 이름을 가진 Control의 Background GradientStops 묶음 중 1번(0번부터 시작)에 해당하는 색을 ControlMouseOverColor로 바꾸는 것]입니다.
⭐ 원래 EasingcolorKeyFrame의 KeyTime만큼의 시간을 걸려서 색을 바꾸지만 예제에서는 0이기 때문에 바로 바뀝니다.

Pressed
 Storyboard의 내용을 풀어보면 ["Border"라는 이름을 가진 Control의 Background GradientStops 묶음 중 1번에 해당하는 색을 ControlPressedColor로 바꾸고,  BorderBrush GradientStops 묶음 중 0번과 1번의 색을 PressedBorderDarkColor와 PressedBorderLightColor로 바꾸는 것]입니다.

⭐ Normal과 Disabled의 경우 Storyboard가 존재하지 않지만 명시해주지 않으면 상태가 Normal이나 Disabled로 변할 때 외형이 바뀌지 않습니다.

ColorAnimationUsingKeyFrames
 KeyFrames 집합을 따라 Color 속성 값에 EasingColorKeyFrame의 애니메이션 효과를 줍니다.

 

 

CheckStates

<VisualStateGroup x:Name="CheckStates">
    <VisualState x:Name="Checked">
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="CheckMark">
                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
    <VisualState x:Name="Unchecked" />
    <VisualState x:Name="Indeterminate">
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="InderminateMark">
                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
</VisualStateGroup>
Checked & Indeterminate
 2가지 모두 Storyboard의 내용을 풀어보면 [Control의 Visibility를 Visible로 바꾸는 것]으로 Control 대상만 다릅니다. Checked의 경우 "CheckMark"라는 이름을 가진 Control이고 Indeterminate의 경우 "InderminateMark"라는 이름을 가진 Control입니다.
⭐ Unchecked의 경우 Storyboard가 존재하지 않지만 명시해주지 않으면 상태가 Checked에서 Unchecked로 변할 때 외형이 바뀌지 않습니다.

⭐ Checked/Unchecked는 IsChecked의 true/false 상태입니다.
⭐ Inderminate는 IsThreeState가 true이고 IsChecked가 null인 상태입니다.

ObjectAnimationusingKeyFrames
 지정된 Object에 대해 KeyFrames 집합을 따라 Duration 속성 값에 애니메이션 효과를 줍니다.

DiscreteObjectKeyFrame
 불연속 보간을 사용하여 이전 Key Frame의 Object 값에서 Value로 애니메이션 효과를 적용합니다.

 

 

 


 

 

전체 코드

더보기
<Style x:Key="{x:Type CheckBox}"
       TargetType="{x:Type CheckBox}">
  <Setter Property="SnapsToDevicePixels"
          Value="true" />
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="FocusVisualStyle"
          Value="{DynamicResource CheckBoxFocusVisual}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type CheckBox}">
        <BulletDecorator Background="Transparent">
          <BulletDecorator.Bullet>
            <Border x:Name="Border"
                    Width="13"
                    Height="13"
                    CornerRadius="0"
                    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 StartPoint="0,0"
                                     EndPoint="0,1">
                  <LinearGradientBrush.GradientStops>
                    <GradientStopCollection>
                      <GradientStop Color="{DynamicResource ControlLightColor}" />
                      <GradientStop Color="{DynamicResource ControlMediumColor}"
                                    Offset="1.0" />
                    </GradientStopCollection>
                  </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>

              </Border.Background>
              <Grid>
                <Path Visibility="Collapsed"
                      Width="7"
                      Height="7"
                      x:Name="CheckMark"
                      SnapsToDevicePixels="False"
                      StrokeThickness="2"
                      Data="M 0 0 L 7 7 M 0 7 L 7 0">
                  <Path.Stroke>
                    <SolidColorBrush Color="{DynamicResource GlyphColor}" />
                  </Path.Stroke>
                </Path>
                <Path Visibility="Collapsed"
                      Width="7"
                      Height="7"
                      x:Name="InderminateMark"
                      SnapsToDevicePixels="False"
                      StrokeThickness="2"
                      Data="M 0 7 L 7 0">
                  <Path.Stroke>
                    <SolidColorBrush Color="{DynamicResource GlyphColor}" />
                  </Path.Stroke>
                </Path>
              </Grid>
            </Border>
          </BulletDecorator.Bullet>
          <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>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Border.BorderBrush).
                      (GradientBrush.GradientStops)[0].(GradientStop.Color)">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource PressedBorderDarkColor}" />
                  </ColorAnimationUsingKeyFrames>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Border.BorderBrush).
                      (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource PressedBorderLightColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Disabled" />
            </VisualStateGroup>
            <VisualStateGroup x:Name="CheckStates">
              <VisualState x:Name="Checked">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                 Storyboard.TargetName="CheckMark">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="{x:Static Visibility.Visible}" />
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Unchecked" />
              <VisualState x:Name="Indeterminate">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                 Storyboard.TargetName="InderminateMark">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="{x:Static Visibility.Visible}" />
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <ContentPresenter Margin="4,0,0,0"
                            VerticalAlignment="Center"
                            HorizontalAlignment="Left"
                            RecognizesAccessKey="True" />
        </BulletDecorator>
      </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/checkbox-styles-and-templates?view=netframeworkdesktop-4.8 

 

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

CheckBox 스타일 및 템플릿 아티클 04/18/2022 읽는 데 3분 걸림 기여자 1명 이 문서의 내용 --> 이 항목에서는 컨트롤의 스타일 및 템플릿에 CheckBox 대해 설명합니다. 기본값을 수정할 수 있습니다 Contro

docs.microsoft.com

 

반응형

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

ComboBox②  (0) 2022.05.10
ComboBox①  (0) 2022.05.09
Calendar③  (0) 2022.05.04
Calendar②  (0) 2022.05.04
Calendar①  (0) 2022.05.03