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

Slider

(ㅇㅅㅎ) 2022. 6. 18. 22:21
728x90
반응형

 

 안녕하세요, 이번 글에서는 Microsoft에서 제공하는 WPF [Slider의 스타일 및 템플릿] 예제를 톺아보겠습니다. Slider Style의 경우 SliderButtonStyle, SliderThumbStyle, HorizontalSlider, VerticalSliderSlider 순서로 나눠져 있습니다. 이번 글에서는 Slider, HorizontalSlider&VerticalSliderSliderButtonStyle 순서로 보도록 하겠습니다.

SliderThumbStyle은 [Thumb의 스타일 및 템플릿] 예제와 동일합니다.

 

 

 

Slider

 Thumb을 따라 Track Control을 이동하여 값 범위에서 선택할 수 있는 Control을 나타냅니다. 

 

 

 

Slider Style

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

 

 

Slider 속성

<Style TargetType="{x:Type Slider}">
  <Setter Property="SnapsToDevicePixels" Value="true" />
  <Setter Property="OverridesDefaultStyle" Value="true" />
  <Style.Triggers>
    ...
  </Style.Triggers>
</Style>

TargetType

 이 Style을 적용할 형식을 설정합니다.

 

 

SnapsToDevicePixels

 렌더링 하는 동안 Slider의 렌더링에 디바이스 관련 픽셀 스냅(Pixel Snap)을 사용할지 여부를 설정합니다. 픽셀 스냅을 사용하면 값을 true로 설정하고 그렇지 않으면 false로 설정합니다.

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

더보기

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


 

 

OverridesDefaultSytle

 테마 스타일의 스타일 속성을 포함할지 여부를 설정합니다. 이 요소가 테마 스타일 속성을 사용하지 않으면 true이고 사용하면 false입니다.

 

 

Slider 이벤트

 Slider Style에서는 Orientation 이벤트를 Trigger로 표현하였습니다.

 

Triggers

<Style.Triggers>
  <Trigger Property="Orientation" Value="Horizontal">
    <Setter Property="MinWidth" Value="104" />
    <Setter Property="MinHeight" Value="21" />
    <Setter Property="Template" Value="{StaticResource HorizontalSlider}" />
  </Trigger>
  <Trigger Property="Orientation" Value="Vertical">
    <Setter Property="MinWidth" Value="21" />
    <Setter Property="MinHeight" Value="104" />
    <Setter Property="Template" Value="{StaticResource VerticalSlider}" />
  </Trigger>
</Style.Triggers>

 Trigger는 어떤 조건이나 이벤트 등이 주어졌을 때 Control의 상태 또는 이벤트 핸들러 등을 호출하는 기능을 의미합니다. 예제에서는 Orientation의 값에 따라서 MinWidth, MinHeight와 Template를 변경합니다.

 

 

 


 

 

 

HorizontalSlider & VerticalSlider

 예제에서 사용된 HorizontalSliderVerticalSlider는 Slider의 Orientation의 값에 따라서 Slider Template에 사용할 ControlTemplate을 미리 정의해둔 것입니다.

 

 

HorizontalSlider & VerticalSlider Template 구성

<ControlTemplate x:Key="HorizontalSlider" TargetType="{x:Type Slider}">
  <Grid>
    ...
    <TickBar x:Name="TopTick" ... > ... </TickBar>
    <Border x:Name="TrackBackground" ... > ... </Border>
    <Track ... x:Name="PART_Track"> ... </Track>
    <TickBar x:Name="BottomTick" ... />
  </Grid>
  
  <ControlTemplate.Triggers> ... </ControlTemplate.Triggers>
</ControlTemplate>

<ControlTemplate x:Key="VerticalSlider" TargetType="{x:Type Slider}">
  <Grid>
    ...
    <TickBar x:Name="TopTick" ... > ... </TickBar>
    <Border x:Name="TrackBackground" ... > ... </Border>
    <Track ... x:Name="PART_Track"> ... </Track>
    <TickBar x:Name="BottomTick" ... />
  </Grid>
  
  <ControlTemplate.Triggers> ... </ControlTemplate.Triggers>
</ControlTemplate>

Grid

 열 및 행으로 구성되는 유연한 모눈 영역을 정의합니다.

⭐ Grid 속성

더보기

[ Horizontal ]

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  ...
</Grid>

[ Vertical ]

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="Auto" MinWidth="{TemplateBinding MinWidth}" />
    <ColumnDefinition Width="Auto" />
  </Grid.ColumnDefinitions>
  ...
</Grid>

 

RowDefinitions

 Grid에서 RowDefinition을 사용하여 RowDefinitionCollection(RowDefinition 개체의 순서가 지정된 컬렉션)을 설정합니다.

 

RowDefinition

 Grid 요소에 적용되는 행 별 속성을 정의합니다. Height로 높이를 숫자 값, 'Auto' 또는 '*'로 설정할 수 있습니다.

 

ColumnDefinitions

 Grid에서 ColumnDeifinition을 사용하여 ColumnDefinitionCollection(ColumnDefinition 개체의 순서가 지정된 컬렉션)을 설정합니다.

 

ColumnDefinition

 Grid 요소에 적용되는 열 별 속성을 정의합니다. Width로 너비를 숫자 값, 'Auto' 또는 '*'로 설정할 수 있습니다.


 

TickBar

 Slider Control의 눈금 표시 집합을 그리는 Control을 나타냅니다.

⭐ TickBar 속성

더보기

[ TopTick ]

<!-- Horizontal -->
<TickBar x:Name="TopTick" SnapsToDevicePixels="True" Placement="Top" Height="4" Visibility="Collapsed">
  <TickBar.Fill>
    <SolidColorBrush Color="{DynamicResource GlyphColor}" />
  </TickBar.Fill>
</TickBar>
<!-- Vertical -->
<TickBar x:Name="TopTick" SnapsToDevicePixels="True" Placement="Left" Width="4" Visibility="Collapsed">
  <TickBar.Fill>
    <SolidColorBrush Color="{DynamicResource GlyphColor}" />
  </TickBar.Fill>
</TickBar>

[ BottomTick ]

<!-- Horizontal -->
<TickBar x:Name="BottomTick" SnapsToDevicePixels="True" Grid.Row="2" Fill="{TemplateBinding Foreground}" Placement="Bottom" Height="4" Visibility="Collapsed" />
<!-- Vertical -->
<TickBar x:Name="BottomTick" SnapsToDevicePixels="True" Grid.Column="2" Fill="{TemplateBinding Foreground}" Placement="Right" Width="4" Visibility="Collapsed" />

 

x:Name

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

🙄 HorizontalSliderVerticalSlider에서 TopTick과 BottomTick으로 설정한 이유는 Trigger 이벤트에서 수정을 적게 하려는 의도 같습니다.

 

SnapsToDevicePixels

 렌더링 하는 동안 TickBar의 렌더링에 디바이스 관련 픽셀 스냅(Pixel Snap)을 사용할지 여부를 설정합니다. 픽셀 스냅을 사용하면 값을 true로 설정하고 그렇지 않으면 false로 설정합니다.

 

Placement

 눈금이 Track의 Slider 기준으로 표시되는 위치를 설정합니다.

 

Hieght

 TickBar의 높이를 설정합니다.

 

Visibility

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

 

Fill

 도형의 내부 색을 설정합니다. 예제에서는 SolidColorBrush를 사용하여 미리 정의되어 있는 색인 GlyphColor로 설정하거나 TemplateBinding을 사용하여 부모의 Foreground로 설정했습니다.

 

Grid.Row

 TickBar을 표시할 Grid의 행 값을 설정합니다.

 

Grid.Column

 TickBar을 표시할 Grid의 열 값을 설정합니다.


 

Border

 다른 요소의 주위에 윤곽선, 배경 또는 둘 다를 그립니다.

⭐ Border 속성

더보기

[ Horizontal ]

<Border x:Name="TrackBackground" Margin="0" CornerRadius="2" Height="4" Grid.Row="1" 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}" Offset="0.0" />
          <GradientStop Color="{DynamicResource SliderTrackDarkColor}" Offset="1.0" />
        </GradientStopCollection>
      </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
  </Border.Background>
</Border>

[ Vertical

<Border x:Name="TrackBackground" Margin="0" CornerRadius="2" Width="4" Grid.Column="1" BorderThickness="1">
  <Border.BorderBrush>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
      <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="1,0" StartPoint="0.25,0">
      <GradientStop Color="{DynamicResource ControlLightColor}" Offset="0" />
      <GradientStop Color="{DynamicResource SliderTrackDarkColor}" Offset="1" />
    </LinearGradientBrush>
  </Border.Background>
</Border>

 

x:Name

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

 

Margin

 Border의 외부 여백을 설정합니다. 예제에서는 0으로 설정하였기 때문에 이 속성을 사용하지 않은 것과 같습니다.

 

CornerRadius

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

 

Width

 Border의 너비를 설정합니다.

 

Grid.Column

 Border를 표시할 Grid의 열 값을 설정합니다.

 

BorderThickness

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

 

BorderBrush

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

 

Background

 Border의 배경색을 설정합니다. 예제에서는 LinearGradientBrush를 사용하여 그라데이션 색으로 설정했습니다.

👀 그라데이션 색에 대해서 알고 싶으신 분은 이 페이지를 참고하시길 바랍니다.


 

Track

 Thumb를 설정하는 데 사용되는 RepeatButton Control과 두 Value Control의 위치와 크기를 지정하는 Control 기본 형식을 나타냅니다.

⭐ Track 속성

더보기

[ Horizontal ]

<Track Grid.Row="1" x:Name="PART_Track">
  <Track.DecreaseRepeatButton>
    <RepeatButton Style="{StaticResource SliderButtonStyle}" Command="Slider.DecreaseLarge" />
  </Track.DecreaseRepeatButton>
  <Track.Thumb>
    <Thumb Style="{StaticResource SliderThumbStyle}" />
  </Track.Thumb>
  <Track.IncreaseRepeatButton>
    <RepeatButton Style="{StaticResource SliderButtonStyle}" Command="Slider.IncreaseLarge" />
  </Track.IncreaseRepeatButton>
</Track>

[ Vertical ]

<Track Grid.Column="1" x:Name="PART_Track">
  <Track.DecreaseRepeatButton>
    <RepeatButton Style="{StaticResource SliderButtonStyle}" Command="Slider.DecreaseLarge" />
  </Track.DecreaseRepeatButton>
  <Track.Thumb>
    <Thumb Style="{StaticResource SliderThumbStyle}" />
  </Track.Thumb>
  <Track.IncreaseRepeatButton>
    <RepeatButton Style="{StaticResource SliderButtonStyle}" Command="Slider.IncreaseLarge" />
  </Track.IncreaseRepeatButton>
</Track>

 

Grid.Row

 Track을 표시할 Grid의 행 값을 설정합니다.

 

Grid.Column

 Track을 표시할 Grid의 열 값을 설정합니다.

 

x:Name

 Track에 이름을 설정합니다. 이름을 설정하는 것과 동시에 다른 곳에서 사용할 수 있도록 만들어줍니다. 예제에서는 Slider Control의 명명된 부분인 PART_Track으로 설정했습니다.

🌟 PART_Track : Slider의 위치를 나타내는 요소에 대한 Container입니다.

 

DecreaseRepeatButton

 RepeatButton의 Value 속성을 감소시키는 Track을 설정합니다. 예제에서는 SliderButtonStyle 스타일과 Command 값으로 Slider.DecreaseLarge를 가진 RepeatButton으로 설정했습니다.

🌟 Slider.DecreaseLarge : Slider 값을 LargeChange 속성 값만큼 줄이는 명령

  

Thumb

 Thumb의 Value를 변경하는 데 사용되는 Track Control을 설정합니다. 예제에서는 SliderThumbStyle 스타일을 가진 Thumb로 설정했습니다.

 

IncreaseRepeatButton

 RepeatButton의 Value 속성을 증가시키는 Track을 설정합니다. 예제에서는 SliderButtonStyle 스타일과 Command 값으로 Slider.IncreaseLarge를 가진 RepeatButton으로 설정했습니다.

🌟 Slider.IncreaseLarge : Slider 값을 LargeChange 속성 값만큼 늘리는 명령


 

 

HorizontalSlider & VerticalSlider 이벤트

 예제에서는 이벤트로 TickPlacement의 변화를 Trigger로 표현하였습니다.

⭐ TickPlacement : Slider 기준으로 Track 눈금의 위치를 설정합니다.

 

Triggers

<ControlTemplate.Triggers>
  <Trigger Property="TickPlacement" Value="TopLeft">
    <Setter TargetName="TopTick" Property="Visibility" Value="Visible" />
  </Trigger>
  <Trigger Property="TickPlacement" Value="BottomRight">
    <Setter TargetName="BottomTick" Property="Visibility" Value="Visible" />
  </Trigger>
  <Trigger Property="TickPlacement" Value="Both">
    <Setter TargetName="TopTick" Property="Visibility" Value="Visible" />
    <Setter TargetName="BottomTick" Property="Visibility" Value="Visible" />
  </Trigger>
</ControlTemplate.Triggers>

 Trigger는 어떤 조건이나 이벤트 등이 주어졌을 때 Control의 상태 또는 이벤트 핸들러 등을 호출하는 기능을 의미합니다. 예제에서는 TickPlacement의 값에 따라서 TopTick과 BottomTick의 Visibility 값을 변경합니다.

 

 

 


 

 

 

SliderButtonStyle

 예제에서 사용된 SliderButtonStyle은 ScrollBar의 RepeatButton에 사용할 Style을 미리 정의해둔 것입니다.

 

 

SliderButtonStyle 속성

<Style x:Key="SliderButtonStyle" TargetType="{x:Type RepeatButton}">
  <Setter Property="SnapsToDevicePixels" Value="true" />
  <Setter Property="OverridesDefaultStyle" Value="true" />
  <Setter Property="IsTabStop" Value="false" />
  <Setter Property="Focusable" Value="false" />
  <Setter Property="Template">
    <Setter.Value>
      ...
    </Setter.Value>
  </Setter>
</Style>

x:Key

 XAML 정의 사전에서 만들고 참고하는 요소를 고유하게 식별합니다.

 

 

TargetType

 이 Style을 적용할 형식을 설정합니다.

 

 

SnapsToDevicePixels

 렌더링 하는 동안 SliderButtonStyle의 렌더링에 디바이스 관련 픽셀 스냅(Pixel Snap)을 사용할지 여부를 설정합니다. 픽셀 스냅을 사용하면 값을 true로 설정하고, 그렇지 않으면 false로 설정합니다.

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

더보기

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


 

 

OverridesDefaultStyle

 테마 스타일의 스타일 속성을 포함할지 여부를 설정합니다. 이 요소가 테마 스타일 속성을 사용하지 않으면 true이고 사용하면 false입니다.

 

 

IsTabStop

 SliderButtonStyle이 탭 탐색에 포함되는지 여부를 설정합니다. 탭 탐색에 포함되면 true이고 그렇지 않으면 false입니다.

 

 

Focusable

 SliderButtonStyle이 focus를 받을 수 있는지 여부를 설정합니다. focus를 받을 수 있으면 true이고 받을 수 없으면 false입니다.

 

 

Template

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type RepeatButton}">
      <Border Background="Transparent" />
    </ControlTemplate>
  </Setter.Value>
</Setter>

 SliderButtonStyle의 템플릿을 설정합니다. 예제에서 사용되는 Template는 SliderButtonStyle의 외형을 지정해줄 수 있는 ControlTemplate입니다.

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

 

 

SliderButtonStyle Template 구성

 SliderButtonStyle은 Border 1개로 구성되어있습니다.

Border

 다른 요소의 주위에 윤곽선, 배경 또는 둘 다를 그립니다.

⭐ Border 속성

Background

 Border의 배경색을 설정합니다. 예제에서는 Transparent(투명)로 설정했습니다.

 

 

 


 

 

 

전체 코드

더보기
<Style x:Key="SliderButtonStyle"
       TargetType="{x:Type RepeatButton}">
  <Setter Property="SnapsToDevicePixels"
          Value="true" />
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="IsTabStop"
          Value="false" />
  <Setter Property="Focusable"
          Value="false" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type RepeatButton}">
        <Border Background="Transparent" />
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<Style x:Key="SliderThumbStyle"
       TargetType="{x:Type Thumb}">
  <Setter Property="SnapsToDevicePixels"
          Value="true" />
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="Height"
          Value="14" />
  <Setter Property="Width"
          Value="14" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Thumb}">
        <Ellipse x:Name="Ellipse"
                 StrokeThickness="1">
          <Ellipse.Stroke>
            <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>
          </Ellipse.Stroke>
          <Ellipse.Fill>
            <LinearGradientBrush EndPoint="0.5,1"
                                 StartPoint="0.5,0">
              <GradientStop Color="{DynamicResource ControlMediumColor}"
                            Offset="1" />
              <GradientStop Color="{DynamicResource ControlLightColor}" />
            </LinearGradientBrush>
          </Ellipse.Fill>
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal" />
              <VisualState x:Name="MouseOver">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
                    (GradientBrush.GradientStops)[0].(GradientStop.Color)"
                                                Storyboard.TargetName="Ellipse">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource ControlMouseOverColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Pressed">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
                    (GradientBrush.GradientStops)[0].(GradientStop.Color)"
                                                Storyboard.TargetName="Ellipse">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource ControlPressedColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Disabled">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).
                    (GradientBrush.GradientStops)[0].(GradientStop.Color)"
                                                Storyboard.TargetName="Ellipse">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource DisabledControlDarkColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
        </Ellipse>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!--Template when the orientation of the Slider is Horizontal.-->
<ControlTemplate x:Key="HorizontalSlider"
                 TargetType="{x:Type Slider}">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto"
                     MinHeight="{TemplateBinding MinHeight}" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <TickBar x:Name="TopTick"
             SnapsToDevicePixels="True"
             Placement="Top"
             Height="4"
             Visibility="Collapsed">
      <TickBar.Fill>
        <SolidColorBrush Color="{DynamicResource GlyphColor}" />
      </TickBar.Fill>
    </TickBar>
    <Border x:Name="TrackBackground"
            Margin="0"
            CornerRadius="2"
            Height="4"
            Grid.Row="1"
            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}"
                            Offset="0.0" />
              <GradientStop Color="{DynamicResource SliderTrackDarkColor}"
                            Offset="1.0" />
            </GradientStopCollection>
          </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>
      </Border.Background>
    </Border>
    <Track Grid.Row="1"
           x:Name="PART_Track">
      <Track.DecreaseRepeatButton>
        <RepeatButton Style="{StaticResource SliderButtonStyle}"
                      Command="Slider.DecreaseLarge" />
      </Track.DecreaseRepeatButton>
      <Track.Thumb>
        <Thumb Style="{StaticResource SliderThumbStyle}" />
      </Track.Thumb>
      <Track.IncreaseRepeatButton>
        <RepeatButton Style="{StaticResource SliderButtonStyle}"
                      Command="Slider.IncreaseLarge" />
      </Track.IncreaseRepeatButton>
    </Track>
    <TickBar x:Name="BottomTick"
             SnapsToDevicePixels="True"
             Grid.Row="2"
             Fill="{TemplateBinding Foreground}"
             Placement="Bottom"
             Height="4"
             Visibility="Collapsed" />
  </Grid>
  <ControlTemplate.Triggers>
    <Trigger Property="TickPlacement"
             Value="TopLeft">
      <Setter TargetName="TopTick"
              Property="Visibility"
              Value="Visible" />
    </Trigger>
    <Trigger Property="TickPlacement"
             Value="BottomRight">
      <Setter TargetName="BottomTick"
              Property="Visibility"
              Value="Visible" />
    </Trigger>
    <Trigger Property="TickPlacement"
             Value="Both">
      <Setter TargetName="TopTick"
              Property="Visibility"
              Value="Visible" />
      <Setter TargetName="BottomTick"
              Property="Visibility"
              Value="Visible" />
    </Trigger>
  </ControlTemplate.Triggers>
</ControlTemplate>

<!--Template when the orientation of the Slider is Vertical.-->
<ControlTemplate x:Key="VerticalSlider"
                 TargetType="{x:Type Slider}">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition Width="Auto"
                        MinWidth="{TemplateBinding MinWidth}" />
      <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <TickBar x:Name="TopTick"
             SnapsToDevicePixels="True"
             Placement="Left"
             Width="4"
             Visibility="Collapsed">
      <TickBar.Fill>
        <SolidColorBrush Color="{DynamicResource GlyphColor}" />
      </TickBar.Fill>
    </TickBar>

    <Border x:Name="TrackBackground"
            Margin="0"
            CornerRadius="2"
            Width="4"
            Grid.Column="1"
            BorderThickness="1">
      <Border.BorderBrush>
        <LinearGradientBrush StartPoint="0,0"
                             EndPoint="1,0">
          <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="1,0"
                             StartPoint="0.25,0">
          <GradientStop Color="{DynamicResource ControlLightColor}"
                        Offset="0" />
          <GradientStop Color="{DynamicResource SliderTrackDarkColor}"
                        Offset="1" />
        </LinearGradientBrush>
      </Border.Background>
    </Border>
    <Track Grid.Column="1"
           x:Name="PART_Track">
      <Track.DecreaseRepeatButton>
        <RepeatButton Style="{StaticResource SliderButtonStyle}"
                      Command="Slider.DecreaseLarge" />
      </Track.DecreaseRepeatButton>
      <Track.Thumb>
        <Thumb Style="{StaticResource SliderThumbStyle}" />
      </Track.Thumb>
      <Track.IncreaseRepeatButton>
        <RepeatButton Style="{StaticResource SliderButtonStyle}"
                      Command="Slider.IncreaseLarge" />
      </Track.IncreaseRepeatButton>
    </Track>
    <TickBar x:Name="BottomTick"
             SnapsToDevicePixels="True"
             Grid.Column="2"
             Fill="{TemplateBinding Foreground}"
             Placement="Right"
             Width="4"
             Visibility="Collapsed" />
  </Grid>
  <ControlTemplate.Triggers>
    <Trigger Property="TickPlacement"
             Value="TopLeft">
      <Setter TargetName="TopTick"
              Property="Visibility"
              Value="Visible" />
    </Trigger>
    <Trigger Property="TickPlacement"
             Value="BottomRight">
      <Setter TargetName="BottomTick"
              Property="Visibility"
              Value="Visible" />
    </Trigger>
    <Trigger Property="TickPlacement"
             Value="Both">
      <Setter TargetName="TopTick"
              Property="Visibility"
              Value="Visible" />
      <Setter TargetName="BottomTick"
              Property="Visibility"
              Value="Visible" />
    </Trigger>
  </ControlTemplate.Triggers>
</ControlTemplate>

<Style TargetType="{x:Type Slider}">
  <Setter Property="SnapsToDevicePixels"
          Value="true" />
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Style.Triggers>
    <Trigger Property="Orientation"
             Value="Horizontal">
      <Setter Property="MinWidth"
              Value="104" />
      <Setter Property="MinHeight"
              Value="21" />
      <Setter Property="Template"
              Value="{StaticResource HorizontalSlider}" />
    </Trigger>
    <Trigger Property="Orientation"
             Value="Vertical">
      <Setter Property="MinWidth"
              Value="21" />
      <Setter Property="MinHeight"
              Value="104" />
      <Setter Property="Template"
              Value="{StaticResource VerticalSlider}" />
    </Trigger>
  </Style.Triggers>
</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/slider-styles-and-templates?view=netframeworkdesktop-4.8 

 

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

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

docs.microsoft.com

 

반응형

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

TabControl  (0) 2022.06.20
StatusBar  (0) 2022.06.19
ScrollViewer  (0) 2022.06.17
ScrollBar②  (0) 2022.06.17
ScrollBar①  (0) 2022.06.17