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

ListView②

(ㅇㅅㅎ) 2022. 6. 1. 23:41
728x90
반응형

 

 안녕하세요, 이번 글에서는 지난 글에 이어서 Microsoft에서 제공하는 WPF [ListView의 스타일 및 템플릿] 예제를 톺아보겠습니다. ListView Style의 경우 Style들이 ScrollViewer, Thumb, GridViewColumnHeader, ListView, ListViewItem 순서로 나눠져 있습니다. 이번 글에서는 ScrollViewer, GridViewColumnHeaderThumb에 대해서 보도록 하겠습니다.

 

 

 

[ ScrollViewer Style ]

 예제에서 사용된 ScrollViewer는 GridView.GridViewScrollViewerStyleKey에 사용할 Style을 미리 정의해둔 것입니다. 이 GridView.GridViewScrollViewerStyleKey는 ListView의 Scroll에서 사용되기 때문에, 쉽게 생각하면 ListViewScrollViewer 부분을 Style로 미리 정의해둔 것입니다.

 

 

 

ScrollViewer 속성

<Style x:Key="{x:Static GridView.GridViewScrollViewerStyleKey}" TargetType="ScrollViewer">
  <Setter Property="Template">
    <Setter.Value>
      ...
    </Setter.Value>
  </Setter>
</Style>

x:Key

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

 

 

TargetType

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

 

 

Template

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="ScrollViewer">
      <Grid ... >
        ...
        <DockPanel ... >
          <ScrollViewer ... >
            <GridViewHeaderRowPresenter ... />
          </ScrollViewer>
          <ScrollContentPresenter Name="PART_ScrollContentPresenter" ... />
        </DockPanel>
        <ScrollBar Name="PART_HorizontalScrollBar" ... /> 
        <ScrollBar Name="PART_VerticalScrollBar" ... />
      </Grid>
    </ControlTemplate>
  </Setter.Value>
</Setter>

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

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

 

 

 

ScrollViewer Template 구성

 ScrollViewer Style은 DockPanel으로 ScrollViewerScrollContentPresenter를 구성하였습니다.

 

Grid

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

Grid 속성

더보기
<Grid Background="{TemplateBinding Background}">
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="Auto" />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="*" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  ...
</Grid>

 

Background

 Grid의 배경색을 설정합니다. 예제에서는 TemplateBinding을 사용하여 ScrollViewer의 Background 값으로 설정했습니다.

 

ColumnDefinitions

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

 

ColumnDefinition

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

 

RowDefinitions

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

 

RowDefinition

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


 

DockPanel

 자식 요소를 서로 맞춰 가로 또는 세로로 정렬할 수 있는 영역을 정의합니다.

DockPanel 속성

더보기
<DockPanel Margin="{TemplateBinding Padding}">
  ...
</DockPanel>

 

Margin

 DockPanel의 외부 여백을 설정합니다. 예제에서는 TemplateBinding을 사용하여 부모의 Padding 값으로 설정했습니다.


⭐ DocPanel에서 알아두면 좋은 간단한 정보

더보기

 Doc은 자식 Control에서 DocPanel.Doc을 사용하여 설정합니다. 값으로는 Left, Top, Right, Bottom이 있습니다. Control의 순서에 따라서 구성 유형이 달라질 수 있습니다.

 기본 설정인 DockPanel.LastCHildFill 속성을 true(기본값)로 설정하는 경우 DockPanel의 마지막 자식 요소는 마지막 자식 요소에 설정한 다른 dock 값에 관계없이 항상 나머지 공간을 채웁니다.


 

ScrollViewer

 표시 가능한 다른 요소를 포함할 수 있는 Scroll 가능한 영역을 나타냅니다.

ScrollViewer 속성

더보기
<ScrollViewer DockPanel.Dock="Top" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Focusable="false">
  ...
</ScrollViewer>

 

DockPanel.Dock

 Doc 내에 있는 자식 요소의 DockPanel위치를 지정합니다. 값으로는 Left, Top, Right, Bottom이 있습니다.

 

HorizontalScrollBarVisibility

 가로 ScrollBar를 표시해야 하는지 여부를 설정합니다. 기본값은 Hidden이며 다른 값으로 Auto, Disabled, Visible이 있습니다.

 

VerticalScrollBarVisibility

 세로 ScrollBar를 표시해야 하는지 여부를 설정합니다. 기본값은 Visible이며 다른 값으로 Auto, Disabled, Hidden이 있습니다.


 

GridViewHeaderRowPresenter

 열 헤더 행의 레이아웃을 정의하는 데 사용되는 개체를 나타냅니다.

GridVIewHeaderRowPresenter 속성

더보기
<GridViewHeaderRowPresenter Margin="2,0,2,0"
                            Columns="{Binding Path=TemplatedParent.View.Columns, RelativeSource={RelativeSource TemplatedParent}}"
                            ColumnHeaderContainerStyle="{Binding Path=TemplatedParent.View.ColumnHeaderContainerStyle, RelativeSource={RelativeSource TemplatedParent}}"
                            ColumnHeaderTemplate="{Binding Path=TemplatedParent.View.ColumnHeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}"
                            ColumnHeaderTemplateSelector="{Binding Path=TemplatedParent.View.ColumnHeaderTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}"
                            AllowsColumnReorder="{Binding Path=TemplatedParent.View.AllowsColumnReorder, RelativeSource={RelativeSource TemplatedParent}}"
                            ColumnHeaderContextMenu="{Binding Path=TemplatedParent.View.ColumnHeaderContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
                            ColumnHeaderToolTip="{Binding Path=TemplatedParent.View.ColumnHeaderToolTip, RelativeSource={RelativeSource TemplatedParent}}"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />

🌟 Margin과 SnapsToDevicePixels를 제외한 모든 속성들은 Binding을 사용하여 TemplatedParent.View.속성의 값들로 설정했습니다. 예제에서 사용된 ColumnHeaderContainerStyle의 경우 예제에서 정의한 GridViewColumnHeader가 사용되었습니다.

 

Margin

 GridViewHeaderRowPresenter의 외부 여백을 설정합니다. 예제에서는 4개(좌, 상, 우, 하)로 나누어서 설정했습니다.

 

Columns

 GridViewColumnCollection을 설정합니다.

 

ColumnHeaderContainerStyle

 열 머리글에 사용할 Style을 설정합니다.

 

ColumnHeaderTemplate

 열 머리글을 표시하는 데 사용할 템플릿을 설정합니다.

 

ColumnHeaderTemplateSelector

 열 머리글을 표시하는 데 사용할 DataTemplateSelector(데이터 개체와 데이터 바인딩된 요소를 기반으로 하여 DataTemplate을 선택하는 방법)를 설정합니다.

 

AllowsColumnReorder

 열의 위치를 변경할 수 있는지 여부를 설정합니다. 열 머리글의 끌어서 놓기 작업으로 열을 이동할 수 있으면 true(기본값)이고, 그렇지 않으면 false입니다.

 

ColumnHeaderContextMenu

 열 머리글의 ContextMenu를 설정합니다. 

 

ColumnHeaderToolTip

 열 머리글 행의 도구 설명 내용을 가져오거나 설정합니다.

 

SnapsToDevciePixels

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


 

ScrollContentPresenter(PART_ScrollContentPresenter)

 ScrollViewer Control의 내용을 표시합니다.

ScrollContentPresenter 속성

더보기
<ScrollContentPresenter Name="PART_ScrollContentPresenter" KeyboardNavigation.DirectionalNavigation="Local" 
                        CanContentScroll="True" CanHorizontallyScroll="False" CanVerticallyScroll="False" />

 

Name

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

 

KeyboardNavigation.DirectionalNavigation

 이 속성이 설정된 요소의 자식에 대한 방향 탐색 동작을 설정합니다. 값으로는 Contained, Continue, Cycle, Local, None, Once가 있습니다.

👀 값에 대한 자세한 설명은 이 페이지를 참고하시면 됩니다.

 

CanContentScroll

 IScrollInfo가 지원되는 경우 Content가 Scroll을 제어할 수 있는지 여부를 설정합니다. Content를 Scroll 할 수 있으면 true이고, 그렇지 않으면 false입니다.

 

CanHorizontallyScroll

 가로축에서 Scroll이 가능한지 여부를 설정합니다. Scroll이 가능하면 true이고, 가능하지 않으면 false입니다.

 

CanVerticallyScroll

 세로축에서 Scroll이 가능한지 여부를 설정합니다. Scroll이 가능하면 true이고, 가능하지 않으면 false입니다.


 

ScrollBar(PART_HorizontalScrollBar, PART_VerticalScrollBar)

 값에 따라 위치가 지정되는 이동식 Thumb이 있는 스크롤 막대를 제공하는 Control을 나타냅니다.

ScrollBar 속성

더보기
<ScrollBar Name="PART_HorizontalScrollBar" Orientation="Horizontal" Grid.Row="1" Maximum="{TemplateBinding ScrollableWidth}"
           ViewportSize="{TemplateBinding ViewportWidth}" Value="{TemplateBinding HorizontalOffset}"
           Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" /> 
<ScrollBar Name="PART_VerticalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}"
           ViewportSize="{TemplateBinding ViewportHeight}" Value="{TemplateBinding VerticalOffset}"
           Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />

 

Name

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

 

Orientation

 ScrollBar가 세로 방향으로 표시될지 가로 방향으로 표시될지를 설정합니다. 기본값은 Vertical(세로 방향)이며 다른 값으로 Horizontal(가로 방향)이 있습니다.

 

Grid.Row

 표시할 Grid의 행 자식 Content를 나타내는 값을 설정합니다.

 

Grid.Column

 표시할 Grid의 열 자식 Content를 나타내는 값을 설정합니다.

 

Maximum

 범위 요소에서 사용 가능한 가장 높은 Value를 설정합니다. 예제에서는 TemplateBinding을 사용하여 각각 부모의 ScrollableWidth와 ScrollableHeight 값으로 설정했습니다.

 

ViewportSize

 현재 볼 수 있는 Scroll 가능한 Content 양을 설정합니다. 예제에서는 TemplateBinding을 사용하여 각각 부모의 ViewportWidth와 ViewportHeight 값으로 설정했습니다.

 

Value

 범위 Control의 현재 크기를 설정합니다. 예제에서는 TemplateBinding을 사용하여 각각 부모의 HorizontalOffset과 VerticalOffset 값으로 설정했습니다.

 

Visibility

 ScorllBar의 표시 유형을 설정합니다. 기본값은 Visible이며, 다른 값으로 Collapsed와 Hidden이 있습니다. 예제에서는 TemplateBinding을 사용하여 각각 부모의 ComputedHorizontalScrollBarVisibility와 ComputedVerticalScrollBarVisibility 값으로 설정했습니다.


 

 


 

 

 

[ GridViewColumnHeader Style ]

 예제에서 사용된 GridViewColumnHeader는 GridViewColumnHeader에 사용할 Style을 미리 정의해둔 것입니다. 이 GridViewColumnHeaderListView에서 사용되기 때문에, 쉽게 생각하면 ListView의 GridViewColumnHeader 부분을 Style로 미리 정의해둔 것입니다.

 

 

 

GridViewColumnHeader 속성

<Style x:Key="{x:Type GridViewColumnHeader}" TargetType="GridViewColumnHeader">
  <Setter Property="HorizontalContentAlignment" Value="Center" />
  <Setter Property="VerticalContentAlignment" Value="Center" />
  <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
  <Setter Property="Template">
    <Setter.Value>
      ...
    </Setter.Value>
  </Setter>
  <Style.Triggers>
    ...
  </Style.Triggers>
</Style>

x:Key

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

 

 

TargetType

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

 

 

HorizontalContentAlignment

 Content의 가로 맞춤을 설정합니다. 기본값은 Left이며, 다른 값으로 Stretch, Center, Right가 있습니다.

 

 

VerticalContentAlignment

 Content의 세로 맞춤을 설정합니다. 기본값은 Top이며, 다른 값으로 Stretch, Center, Bottom이 있습니다.

 

 

Foreground

 전경색을 설정합니다. 예제에서는 DynamicResource를 사용하여 미리 정의되어 있는 SystemColors.ControlTextBrushKey로 설정했습니다.

 

 

Template

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="GridViewColumnHeader">
      <Grid>
        ...
        <Border x:Name="HeaderBorder" ... >
          ...
          <ContentPresenter x:Name="HeaderContent" ... />
        </Border>
      <Thumb x:Name="PART_HeaderGripper" ... />
      </Grid>
    </ControlTemplate>
  </Setter.Value>
</Setter>

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

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

 

 

GridViewColumnHeader Template 구성

 GridViewColumnHeader Style은 ContentPresenterBorder가 감싼 형태와 Thumb로 구성되어있습니다.

 

Grid

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

 

Border(HeaderBorder)

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

Border 속성

더보기
<Border x:Name="HeaderBorder" BorderThickness="0,1,0,1" Padding="2,0,2,0">
  <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 ControlMediumColor}" Offset="1.0" />
        </GradientStopCollection>
      </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
  </Border.Background>
  ...
</Border>

 

x:Name

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

 

BorderThickness

 Border의 윤곽선 두께를 설정합니다. 예제에서는 4개(좌, 상, 우, 하)의 값으로 나누어서 설정했습니다.

 

Padding

 Border의 윤곽선과 자식 요소 사이의 간격을 설정합니다. 예제에서는 4개(좌, 상, 우, 하)의 값으로 나누어서 설정했습니다.

 

BorderBrush

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

 

Background

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

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


 

ContentPresenter(HeaderContent)

 모든 유형의 단일 Content로 이루어진 Control을 나타냅니다.

ContentPresenter 속성

더보기
<ContentPresenter x:Name="HeaderContent" Margin="0,0,0,1" RecognizesAccessKey="True"
                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>

 

x:Name

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

 

Margin

 ContentPresenter의 외부 여백을 설정합니다. 예제에서는 값을 4개(좌, 상, 우, 하)로 나누어서 설정했습니다.

 

RecognizesAccessKey

 ContentPresenter의 스타일에 AccessText가 사용되는지 여부를 설정합니다. AccessText가 사용되면 true이고, 그렇지 않으면 false(기본값)입니다.

[ALt]+[N] 키로 확인

 

VerticalAlignment

 ContentPresenter의 세로 정렬 위치를 설정합니다. 예제에서는 TemplateBinding을 사용하여 부모의 VerticalAlignment로 설정했습니다,

 

HorizontalAlignment

 ContentPresenter의 가로 정렬 위치를 설정합니다. 예제에서는 TemplateBinding을 사용하여 부모의 HorizontalContentAlignment로 설정했습니다.

 

SnapsToDevicePixels

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


 

Thumb(PART_HeaderGripper)

 사용자가 끌어올 수 있는 Control을 나타냅니다.

Thumb 속성

더보기
<Thumb x:Name="PART_HeaderGripper" HorizontalAlignment="Right" Margin="0,0,-9,0"
       Style="{StaticResource GridViewColumnHeaderGripper}" />

 

x:Name

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

 

HorizontalAlignment

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

 

Margin

 Thumb의 외부 여백을 설정합니다. 예제에서는 4개(좌, 상, 우, 하)로 나누어서 설정했고 음수 값을 사용하여 Padding 값처럼 내부 여백처럼 설정했습니다.

 

Style

 Style은 Thumb에 속성, 리소스 및 이벤트 처리기를 공유할 수 있게 합니다. 예제에서는 예제에서 정의한 GridViewColumnHeaderGripper로 설정했습니다.


 

 

GridViewColumnHeader 이벤트

 예제에서는 MouseOver 이벤트를 VisualState 그리고 Role 이벤트를 Trigger로 표현하였습니다.

 

VisualStateManager

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

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

 

⭐ CommonStates Event

더보기
<VisualStateGroup x:Name="CommonStates">
  <VisualState x:Name="Normal" />
  <VisualState x:Name="MouseOver">
    <Storyboard>
      <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="HeaderBorder">
        <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ControlMouseOverColor}" />
      </ColorAnimationUsingKeyFrames>
    </Storyboard>
  </VisualState>
  <VisualState x:Name="Pressed" />
  <VisualState x:Name="Disabled" />
</VisualStateGroup>

MouseOver

 Storyboard의 내용을 풀어보면 ["HeaderBorder"라는 이름을 가진 Control의 Background GradientStops 묶음 중 1번(0번부터 시작)을 ControlMouseOverColor로 바꾸는 것]입니다.

🌟 Normal, Pressed, Disabled의 경우 Storyboard가 존재하지 않지만 명시해주지 않으면 MouseOver에서 각각의 상태로 변할 때 MouseOver에서 외형이 바뀌지 않습니다.

 

ColorAnimationUsingKeyFrames

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


 

Triggers

<Style.Triggers>
  <Trigger Property="Role" Value="Floating">
    ...
  </Trigger>
  <Trigger Property="Role" Value="Padding">
    ...
  </Trigger>
</Style.Triggers>

 Trigger는 어떤 조건이나 이벤트 등이 주어졌을 때 Control의 상태 또는 이벤트 핸들러 등을 호출하는 기능을 의미합니다. 예제에서는 Role의 값에 따라서 다른 이벤트로 설정했습니다.

 Role은 GridViewColumnHeader의 역할을 의미합니다. 값으로는 Floating, Normal, Padding이 있습니다.

 

Floating

 열 머리글이 열을 이동하기 위하여 끌어서 놓는 작업을 의미합니다.

⭐ Floating Event

더보기
<Trigger Property="Role" Value="Floating">
  <Setter Property="Opacity" Value="0.7" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="GridViewColumnHeader">
        <Canvas Name="PART_FloatingHeaderCanvas">
          <Rectangle Fill="#60000000" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}" />
        </Canvas>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Trigger>

 

 - Opacity(불투명도)의 값을 0.7로 변경합니다.

 - Template를 다음과 같이 구성을 변경합니다. 간단히 구성을 설명하면 "PART_FloatingHeaderCanvas"라는 이름을 가진 Canvas 내부에 불투명한(16진수로 60 값) 검은색 Rectangle(사각형)을 구성한 것입니다.




Padding

 열 머리글이 열 머리글 행의 마지막 머리글이면 안쪽 여백에 사용하는 것을 의미합니다.

⭐ Padding Event

더보기
<Trigger Property="Role" Value="Padding">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="GridViewColumnHeader">
        <Border Name="HeaderBorder" BorderThickness="0,1,0,1">
          <Border.Background>
            <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
          </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>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Trigger>

 - Template의 "HeaderBorder"의 Background와 BorderBrush를 변경합니다.


 

 

 


 

 

 

[ Thumb Style ]

 예제에서 사용된 Thumb는 GridViewColumnHeaderGripper에 사용할 Style을 미리 정의해둔 것입니다. 

 

 

 

Thumb 속성

<Style x:Key="GridViewColumnHeaderGripper" TargetType="Thumb">
  <Setter Property="Width" Value="18" />
  <Setter Property="Background">
    <Setter.Value>
      ...
    </Setter.Value>
  </Setter>
  <Setter Property="Template">
    <Setter.Value>
      ...
    </Setter.Value>
  </Setter>
  <Setter Property="BorderBrush">
    <Setter.Value>
      ...
    </Setter.Value>
  </Setter>
</Style>

x:Key

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

 

 

TargetType

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

 

 

Width

 Thumb의 너비를 설정합니다.

 

 

Background

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

<Setter Property="Background">
  <Setter.Value>
    <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>
  </Setter.Value>
</Setter>

 

 

BorderBrush

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

<Setter Property="BorderBrush">
  <Setter.Value>
    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
      <GradientStop Color="Black" Offset="0" />
      <GradientStop Color="White" Offset="1" />
    </LinearGradientBrush>
  </Setter.Value>
</Setter>

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

 

 

Template

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type Thumb}">
      ...
    </ControlTemplate>
  </Setter.Value>
</Setter>

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

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

 

 

Thumb Template 구성

 Thumb Style은 RectangleBorder가 감싼 형태로 구성되어있습니다.

 

Border

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

Border 속성

더보기
<Border Padding="{TemplateBinding Padding}" Background="Transparent">
  ...
</Border>

 

Padding

 Border의 윤곽선과 자식 요소 사이의 간격을 설정합니다. 예제에서는 TemplateBinding을 사용하여 부모의 Padding 값으로 설정했습니다.

 

Background

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


 

Rectangle

 사각형을 그립니다.

Rectangle 속성

더보기
<Rectangle HorizontalAlignment="Center" Width="1" Fill="{TemplateBinding Background}" />

 

HorizontalAlignment

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

 

Width

 Rectangle의 너비를 설정합니다.

 

Fill

 도형의 내부 색을 설정합니다. 예제에서는 TemplateBinding을 사용하여 부모의 Background 값으로 설정했습니다.


 

 

 


 

 

 

전체 코드

더보기
<Style x:Key="{x:Static GridView.GridViewScrollViewerStyleKey}"
       TargetType="ScrollViewer">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ScrollViewer">
        <Grid Background="{TemplateBinding Background}">
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>

          <DockPanel Margin="{TemplateBinding Padding}">
            <ScrollViewer DockPanel.Dock="Top"
                          HorizontalScrollBarVisibility="Hidden"
                          VerticalScrollBarVisibility="Hidden"
                          Focusable="false">
              <GridViewHeaderRowPresenter Margin="2,0,2,0"
                                          Columns="{Binding Path=TemplatedParent.View.Columns,
                RelativeSource={RelativeSource TemplatedParent}}"
                                          ColumnHeaderContainerStyle="{Binding
                Path=TemplatedParent.View.ColumnHeaderContainerStyle,
                RelativeSource={RelativeSource TemplatedParent}}"
                                          ColumnHeaderTemplate="{Binding
                Path=TemplatedParent.View.ColumnHeaderTemplate,
                RelativeSource={RelativeSource TemplatedParent}}"
                                          ColumnHeaderTemplateSelector="{Binding 
                Path=TemplatedParent.View.ColumnHeaderTemplateSelector,
                RelativeSource={RelativeSource TemplatedParent}}"
                                          AllowsColumnReorder="{Binding
                Path=TemplatedParent.View.AllowsColumnReorder,
                RelativeSource={RelativeSource TemplatedParent}}"
                                          ColumnHeaderContextMenu="{Binding
                Path=TemplatedParent.View.ColumnHeaderContextMenu,
                RelativeSource={RelativeSource TemplatedParent}}"
                                          ColumnHeaderToolTip="{Binding
                Path=TemplatedParent.View.ColumnHeaderToolTip,
                RelativeSource={RelativeSource TemplatedParent}}"
                                          SnapsToDevicePixels="{TemplateBinding
                SnapsToDevicePixels}" />
            </ScrollViewer>

            <ScrollContentPresenter Name="PART_ScrollContentPresenter"
                                    KeyboardNavigation.DirectionalNavigation="Local"
                                    CanContentScroll="True"
                                    CanHorizontallyScroll="False"
                                    CanVerticallyScroll="False" />
          </DockPanel>

          <ScrollBar Name="PART_HorizontalScrollBar"
                     Orientation="Horizontal"
                     Grid.Row="1"
                     Maximum="{TemplateBinding ScrollableWidth}"
                     ViewportSize="{TemplateBinding ViewportWidth}"
                     Value="{TemplateBinding HorizontalOffset}"
                     Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />

          <ScrollBar Name="PART_VerticalScrollBar"
                     Grid.Column="1"
                     Maximum="{TemplateBinding ScrollableHeight}"
                     ViewportSize="{TemplateBinding ViewportHeight}"
                     Value="{TemplateBinding VerticalOffset}"
                     Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />

        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<Style x:Key="GridViewColumnHeaderGripper"
       TargetType="Thumb">
  <Setter Property="Width"
          Value="18" />
  <Setter Property="Background">
    <Setter.Value>
      <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>
    </Setter.Value>
  </Setter>
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Thumb}">
        <Border Padding="{TemplateBinding Padding}"
                Background="Transparent">
          <Rectangle HorizontalAlignment="Center"
                     Width="1"
                     Fill="{TemplateBinding Background}" />
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
  <Setter Property="BorderBrush">
    <Setter.Value>
      <LinearGradientBrush EndPoint="0.5,1"
                           StartPoint="0.5,0">
        <GradientStop Color="Black"
                      Offset="0" />
        <GradientStop Color="White"
                      Offset="1" />
      </LinearGradientBrush>
    </Setter.Value>
  </Setter>
</Style>

<Style x:Key="{x:Type GridViewColumnHeader}"
       TargetType="GridViewColumnHeader">
  <Setter Property="HorizontalContentAlignment"
          Value="Center" />
  <Setter Property="VerticalContentAlignment"
          Value="Center" />
  <Setter Property="Foreground"
          Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="GridViewColumnHeader">
        <Grid>
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal" />
              <VisualState x:Name="MouseOver">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
                    (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                                Storyboard.TargetName="HeaderBorder">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource ControlMouseOverColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Pressed" />
              <VisualState x:Name="Disabled" />
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <Border x:Name="HeaderBorder"
                  BorderThickness="0,1,0,1"
                  Padding="2,0,2,0">
            <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 ControlMediumColor}"
                                  Offset="1.0" />
                  </GradientStopCollection>
                </LinearGradientBrush.GradientStops>
              </LinearGradientBrush>

            </Border.Background>
            <ContentPresenter x:Name="HeaderContent"
                              Margin="0,0,0,1"
                              RecognizesAccessKey="True"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
          </Border>
          <Thumb x:Name="PART_HeaderGripper"
                 HorizontalAlignment="Right"
                 Margin="0,0,-9,0"
                 Style="{StaticResource GridViewColumnHeaderGripper}" />
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
  <Style.Triggers>
    <Trigger Property="Role"
             Value="Floating">
      <Setter Property="Opacity"
              Value="0.7" />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="GridViewColumnHeader">
            <Canvas Name="PART_FloatingHeaderCanvas">
              <Rectangle Fill="#60000000"
                         Width="{TemplateBinding ActualWidth}"
                         Height="{TemplateBinding ActualHeight}" />
            </Canvas>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Trigger>
    <Trigger Property="Role"
             Value="Padding">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="GridViewColumnHeader">
            <Border Name="HeaderBorder"
                    BorderThickness="0,1,0,1">
              <Border.Background>
                <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
              </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>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Trigger>
  </Style.Triggers>
</Style>

<Style x:Key="{x:Type ListView}"
       TargetType="ListView">
  <Setter Property="SnapsToDevicePixels"
          Value="true" />
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
          Value="Auto" />
  <Setter Property="ScrollViewer.VerticalScrollBarVisibility"
          Value="Auto" />
  <Setter Property="ScrollViewer.CanContentScroll"
          Value="true" />
  <Setter Property="VerticalContentAlignment"
          Value="Center" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ListView">
        <Border Name="Border"
                BorderThickness="1">
          <Border.Background>
            <SolidColorBrush Color="{StaticResource ControlLightColor}" />
          </Border.Background>
          <Border.BorderBrush>
            <SolidColorBrush Color="{StaticResource BorderMediumColor}" />
          </Border.BorderBrush>
          <ScrollViewer Style="{DynamicResource
                        {x:Static GridView.GridViewScrollViewerStyleKey}}">
            <ItemsPresenter />
          </ScrollViewer>
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsGrouping"
                   Value="true">
            <Setter Property="ScrollViewer.CanContentScroll"
                    Value="false" />
          </Trigger>
          <Trigger Property="IsEnabled"
                   Value="false">
            <Setter TargetName="Border"
                    Property="Background">
              <Setter.Value>
                <SolidColorBrush Color="{DynamicResource DisabledBorderLightColor}" />
              </Setter.Value>
            </Setter>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<Style x:Key="{x:Type ListViewItem}"
       TargetType="ListViewItem">
  <Setter Property="SnapsToDevicePixels"
          Value="true" />
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ListBoxItem">
        <Border x:Name="Border"
                Padding="2"
                SnapsToDevicePixels="true"
                Background="Transparent">
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal" />
              <VisualState x:Name="MouseOver" />
              <VisualState x:Name="Disabled" />
            </VisualStateGroup>
            <VisualStateGroup x:Name="SelectionStates">
              <VisualState x:Name="Unselected" />
              <VisualState x:Name="Selected">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource SelectedBackgroundColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="SelectedUnfocused">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource SelectedUnfocusedColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <GridViewRowPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
        </Border>
      </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/listview-styles-and-templates?view=netframeworkdesktop-4.8 

 

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

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

docs.microsoft.com

 

반응형

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

Menu②  (0) 2022.06.07
Menu①  (0) 2022.06.03
ListView①  (0) 2022.05.31
ListBoxItem  (0) 2022.05.30
ListBox  (0) 2022.05.30