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

Frame②

(ㅇㅅㅎ) 2022. 5. 26. 13:33
728x90
반응형

 

 안녕하세요, 이번 글에서는 Microsoft에서 제공하는 WPF [Frame의 스타일 및 템플릿] 예제를 톺아보도록 하겠습니다. Frame Style의 경우 Frame, FrameButtonStyle, FrameMenu, FrameHeaderMenuItem, FrameSubmenuItem 나눠져 있습니다. 이번 글에서는 FrameButtonStyleFrameMenu에 대해서 보도록 하겠습니다.

 

 

 

[ FrameButtonStyle ]

 예제에 사용된 FrameButtonStyleFrame의 Button 부분을 Style로 미리 정의해둔 것입니다.

 

 

 

FrameButtonStyle 속성

<Style x:Key="FrameButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="OverridesDefaultStyle" Value="true" />
    <Setter Property="Command" Value="NavigationCommands.BrowseBack" />
    <Setter Property="Focusable" Value="false" />
    <Setter Property="Template">
        <Setter.Value>
            ...
        </Setter.Value>
    </Setter>
</Style>

x:Key

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

 

 

TargetType

 이 Style을 적용할 형식을 설정합니다. 예제에서는 "{x:Type Button}"으로 설정했습니다.

 

 

OverridesDefaultStyle

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

 

 

Command

 Button을 누를 때 호출할 명령을 설정합니다. 예제에서는 NavigationCommands.BrowseBack(이전 페이지로 이동 명령)으로 설정했습니다.

 

 

Focusable

 focus를 받을 수 있는지 여부를 설정합니다. focus를 받을 수 있으면 true이고, 받을 수 없으면 false(기본값)입니다.

 

 

Template

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
            <Grid>
                ...
                <Ellipse x:Name="Ellipse" ... >
                    ...
                </Ellipse>

                <Path x:Name="Arrow" ... >
                    ...
                </Path>
            </Grid>

            <ControlTemplate.Triggers>
                ...
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Setter.Value>
</Setter>

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

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

 

 

 

FrameButtonStyle 구성

 FrameButtonStyle은 Grid를 사용하여 Ellipse(Ellipse)Path(Arrow)로 구성했습니다.

 

Grid

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

 

Ellipse(Ellipse)

 타원을 그립니다.

Ellipse 속성

더보기
<Ellipse x:Name="Ellipse" StrokeThickness="1" Width="16" Height="16">
    <Ellipse.Stroke>
        <SolidColorBrush Color="{DynamicResource NavButtonFrameColor}" />
    </Ellipse.Stroke>

    <Ellipse.Fill>
        <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>
    </Ellipse.Fill>
</Ellipse>

 

x:Name

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

 

StrokeThickness

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

 

Width

 Ellipse의 너비를 설정합니다.

 

Height

 Ellipse의 높이를 설정합니다.

 

Stroke

 Ellipse 윤곽선의 색을 설정합니다. 예제에서는 SolidColorBrush를 사용하여 미리 정의된 NavButtonFrameColor로 설정했습니다.

 

Fill

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


 

Path(Arrow)

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

Path 속성

더보기
<Path x:Name="Arrow" Margin="0,0,2,0" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 4 0 L 0 4 L 4 8 Z" >
    <Path.Fill>
        <SolidColorBrush Color="{DynamicResource GlyphColor}"/>
    </Path.Fill>
</Path>

 

x:Name

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

 

Margin

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

 

HorizontalAlignment

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

 

VerticalAlignment

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

 

Data

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

👀 Path의 Data에 대해서 알고 싶으신 분은 이 페이지를 참고하시길 바랍니다.

 

Fill

 도형 내부의 색을 설정합니다. 예제에서는 SolidColorBrush를 사용하여 미리 정의된 색 GlyphColor로 했습니다.


 

 

 

FrameButtonStyle 이벤트

 예제에서는 FrameButtonStyle의 VisualStateManager 이벤트로 MouseOver, Pressed, Disabled를 설정하였고, Triggers로 Command의 NavigationCommands.BrowseForward값에 대한 이벤트를 설정했습니다.

 

VisualStateManager

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

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

 

CommonStates

<VisualStateGroup x:Name="CommonStates">
  <VisualState x:Name="Normal" />
  <VisualState x:Name="MouseOver">
      <Storyboard>
          <ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
                                        Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
              <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ControlMouseOverColor}" />
          </ColorAnimationUsingKeyFrames>
      </Storyboard>
  </VisualState>
  <VisualState x:Name="Pressed">
      <Storyboard>
          <ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
                                        Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
              <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ControlPressedColor}" />
          </ColorAnimationUsingKeyFrames>
      </Storyboard>
  </VisualState>
  <VisualState x:Name="Disabled">
      <Storyboard>
          <ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
                                        Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
              <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledControlDarkColor}" />
          </ColorAnimationUsingKeyFrames>
          <ColorAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                        Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
              <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledForegroundColor}" />
          </ColorAnimationUsingKeyFrames>
      </Storyboard>
  </VisualState>
</VisualStateGroup>

MouseOver & Pressed & Disabled
 Storyboard의 내용을 풀어보면 ["Ellipse"라는 이름을 가진 Control의 Fill GradientStops 묶음의 색 중 1번(0번부터 시작)을 각각 ControlMouseOverColor(MouseOver 이벤트), ControlPressedColor(Pressed 이벤트)와 DisabledControlDarkColor(Disabled 이벤트)로 바꾸는 것] 입니다. 그리고 Disabled의 경우 ["Arrow"라는 이름을 가진 Control의 Fill을 DisabledForegroundColor로 바꾸는 것]도 추가됩니다.

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

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

 

Triggers

<ControlTemplate.Triggers>
    <Trigger Property="Command" Value="{x:Static NavigationCommands.BrowseForward}">
        <Setter TargetName="Arrow" Property="Data" Value="M 0 0 L 4 4 L 0 8 z" />
        <Setter TargetName="Arrow" Property="Margin" Value="2,0,0,0" />
    </Trigger>
</ControlTemplate.Triggers>

 Trigger는 어떤 조건이나 이벤트 등이 주어졌을 때 Control의 상태 또는 이벤트 핸들러 등을 호출하는 기능을 의미합니다. 예제에서는 Command의 값이 NavigationCommands.BrowseForward일 경우 "Arrow"의 Data값과 Margin 값을 변경합니다.

 

 


 

 

[ FrameMenu ]

 예제에서 사용된 FrameMenu는 Frame의 Menu 부분을 Style로 미리 정의해둔 것입니다.

 

 

 

FrameMenu 속성

<Style x:Key="FrameMenu" TargetType="{x:Type Menu}">
  <Setter Property="OverridesDefaultStyle" Value="true" />
  <Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
  <Setter Property="IsMainMenu" Value="false" />
  <Setter Property="Template">
    <Setter.Value>
      ...
    </Setter.Value>
  </Setter>
</Style>

x:Key

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

 

 

TargetType

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

 

 

OverridesDefaultStyle

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

 

 

KeyboardNavigation.TabNavigation

 자식 요소에 대한 논리적 탭 탐색 동작을 설정합니다. 값으로는 Contained, Continue, Cycle, Local, None과 Once가 있습니다.

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

 

 

IsMainMenu

 Menu에서 주 Menu 활성화 알림을 받는지 여부를 설정합니다. 활성화 알림을 받으면 true(기본값)이고, 그렇지 않으면 false입니다.

 

 

Template

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type Menu}">
      <DockPanel IsItemsHost="true" />
    </ControlTemplate>
  </Setter.Value>
</Setter>

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

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

 

 

 

FrameMenu 구성

 FrameMenu Style은 DockPanel 1개로 구성되어있습니다.

 

DockPanel

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

⭐ DocPanel 속성

IsItemsHost

 ItemsControl에 의해 생성된 UI(사용자 인터페이스) 항목에 대한 컨테이너임을 나타내는 Panel 값을 설정합니다. 항목 호스트이면 true이고, 그렇지 않으면 false(기본값)입니다.

 

 


 

 

전체 코드

더보기
<!-- Back/Forward Button Style -->

<Style x:Key="FrameButtonStyle"
       TargetType="{x:Type Button}">
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="Command"
          Value="NavigationCommands.BrowseBack" />
  <Setter Property="Focusable"
          Value="false" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Button}">
        <Grid>
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal" />
              <VisualState x:Name="MouseOver">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
                                                Storyboard.TargetProperty="(Shape.Fill).
                      (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource ControlMouseOverColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Pressed">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
                                                Storyboard.TargetProperty="(Shape.Fill).
                      (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource ControlPressedColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Disabled">
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Ellipse"
                                                Storyboard.TargetProperty="(Shape.Fill).
                      (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource DisabledControlDarkColor}" />
                  </ColorAnimationUsingKeyFrames>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Arrow"
                                                Storyboard.TargetProperty="(Shape.Fill).
                      (SolidColorBrush.Color)">
                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource DisabledForegroundColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <Ellipse x:Name="Ellipse"
                   StrokeThickness="1"
                   Width="16"
                   Height="16">
            <Ellipse.Stroke>
              <SolidColorBrush Color="{DynamicResource NavButtonFrameColor}" />
            </Ellipse.Stroke>
            <Ellipse.Fill>
              <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>
            </Ellipse.Fill>
          </Ellipse>

          <Path x:Name="Arrow"
                Margin="0,0,2,0"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Data="M 4 0 L 0 4 L 4 8 Z" >
              <Path.Fill>
                  <SolidColorBrush Color="{DynamicResource GlyphColor}"/>
              </Path.Fill>
          </Path>
        </Grid>
        <ControlTemplate.Triggers>
          <Trigger Property="Command"
                   Value="{x:Static NavigationCommands.BrowseForward}">
            <Setter TargetName="Arrow"
                    Property="Data"
                    Value="M 0 0 L 4 4 L 0 8 z" />
            <Setter TargetName="Arrow"
                    Property="Margin"
                    Value="2,0,0,0" />
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!-- Frame Menu Style -->

<Style x:Key="FrameMenu"
       TargetType="{x:Type Menu}">
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="KeyboardNavigation.TabNavigation"
          Value="None" />
  <Setter Property="IsMainMenu"
          Value="false" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Menu}">
        <DockPanel IsItemsHost="true" />
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!-- Frame Menu Header Style -->

<Style x:Key="FrameHeaderMenuItem"
       TargetType="{x:Type MenuItem}">
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type MenuItem}">
        <Grid>
          <Popup x:Name="PART_Popup"
                 Placement="Bottom"
                 VerticalOffset="2"
                 IsOpen="{TemplateBinding IsSubmenuOpen}"
                 AllowsTransparency="True"
                 Focusable="False"
                 PopupAnimation="Fade">
            <Border x:Name="SubMenuBorder"
                    BorderThickness="1"
                    Background="{DynamicResource MenuPopupBrush}">
              <Border.BorderBrush>
                <SolidColorBrush Color="{StaticResource BorderMediumColor}" />
              </Border.BorderBrush>
              <StackPanel IsItemsHost="true"
                          Margin="2"
                          KeyboardNavigation.TabNavigation="Cycle"
                          KeyboardNavigation.DirectionalNavigation="Cycle" />
            </Border>
          </Popup>

          <Grid x:Name="Panel"
                Width="24"
                Background="Transparent"
                HorizontalAlignment="Right">

            <Border Visibility="Hidden"
                    x:Name="HighlightBorder"
                    BorderThickness="1"
                    CornerRadius="2">
              <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 ControlMouseOverColor}"
                                    Offset="1.0" />
                    </GradientStopCollection>
                  </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>

              </Border.Background>
            </Border>
            <Path x:Name="Arrow"
                  SnapsToDevicePixels="false"
                  HorizontalAlignment="Right"
                  VerticalAlignment="Center"
                  Margin="0,2,4,0"
                  StrokeLineJoin="Round"
                  Data="M 0 0 L 4 4 L 8 0 Z">
              <Path.Stroke>
                <SolidColorBrush Color="{DynamicResource GlyphColor}" />
              </Path.Stroke>
            </Path>
          </Grid>
        </Grid>
        <ControlTemplate.Triggers>
          <Trigger Property="IsHighlighted"
                   Value="true">
            <Setter TargetName="HighlightBorder"
                    Property="Visibility"
                    Value="Visible" />
          </Trigger>
          <Trigger Property="IsSubmenuOpen"
                   Value="true">
            <Setter TargetName="HighlightBorder"
                    Property="BorderBrush">
              <Setter.Value>
                <LinearGradientBrush StartPoint="0,0"
                                     EndPoint="0,1">
                  <GradientBrush.GradientStops>
                    <GradientStopCollection>
                      <GradientStop Color="{DynamicResource BorderDarkColor}"
                                    Offset="0.0" />
                      <GradientStop Color="{DynamicResource BorderMediumColor}"
                                    Offset="1.0" />
                    </GradientStopCollection>
                  </GradientBrush.GradientStops>
                </LinearGradientBrush>
              </Setter.Value>
            </Setter>
            <Setter Property="Background"
                    TargetName="HighlightBorder">
              <Setter.Value>

                <LinearGradientBrush EndPoint="0,1"
                                     StartPoint="0,0">
                  <GradientStop Color="{DynamicResource ControlLightColor}"
                                Offset="0" />
                  <GradientStop Color="{DynamicResource ControlPressedColor}"
                                Offset="0.984" />
                </LinearGradientBrush>
              </Setter.Value>
            </Setter>
          </Trigger>
          <Trigger Property="IsEnabled"
                   Value="false">
            <Setter TargetName="Arrow"
                    Property="Fill">
              <Setter.Value>
                <SolidColorBrush Color="{DynamicResource DisabledForegroundColor}" />
              </Setter.Value>
            </Setter>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!-- Frame Menu Item Style -->

<Style x:Key="FrameSubmenuItem"
       TargetType="{x:Type MenuItem}">
  <Setter Property="OverridesDefaultStyle"
          Value="true" />
  <Setter Property="Header"
          Value="{Binding (JournalEntry.Name)}" />
  <Setter Property="Command"
          Value="NavigationCommands.NavigateJournal" />
  <Setter Property="CommandTarget"
          Value="{Binding TemplatedParent, 
    RelativeSource={RelativeSource AncestorType={x:Type Menu}}}" />
  <Setter Property="CommandParameter"
          Value="{Binding RelativeSource={RelativeSource Self}}" />
  <Setter Property="JournalEntryUnifiedViewConverter.JournalEntryPosition"
          Value="{Binding (JournalEntryUnifiedViewConverter.JournalEntryPosition)}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type MenuItem}">
        <Border BorderThickness="1"
                Name="Border">
          <Grid x:Name="Panel"
                Background="Transparent"
                SnapsToDevicePixels="true"
                Height="35"
                Width="250">
            <Path x:Name="Glyph"
                  SnapsToDevicePixels="false"
                  Margin="7,5"
                  Width="10"
                  Height="10"
                  HorizontalAlignment="Left"
                  StrokeStartLineCap="Triangle"
                  StrokeEndLineCap="Triangle"
                  StrokeThickness="2">
              <Path.Stroke>
                <SolidColorBrush Color="{DynamicResource GlyphColor}" />
              </Path.Stroke>
            </Path>

            <ContentPresenter ContentSource="Header"
                              Margin="24,5,50,5" />
          </Grid>
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="JournalEntryUnifiedViewConverter.JournalEntryPosition"
                   Value="Current">
            <Setter TargetName="Glyph"
                    Property="Data"
                    Value="M 0,5 L 2.5,8 L 7,3 " />
          </Trigger>
          <Trigger Property="IsHighlighted"
                   Value="true">
            <Setter Property="Background"
                    TargetName="Border">
              <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1"
                                     StartPoint="0.5,0">
                  <GradientStop Color="Transparent"
                                Offset="0" />
                  <GradientStop Color="{DynamicResource ControlMouseOverColor}"
                                Offset="1" />
                </LinearGradientBrush>
              </Setter.Value>
            </Setter>
            <Setter Property="BorderBrush"
                    TargetName="Border">
              <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1"
                                     StartPoint="0.5,0">
                  <GradientStop Color="{DynamicResource BorderMediumColor}"
                                Offset="0" />
                  <GradientStop Color="Transparent"
                                Offset="1" />
                </LinearGradientBrush>
              </Setter.Value>
            </Setter>
          </Trigger>
          <MultiTrigger>
            <MultiTrigger.Conditions>
              <Condition Property="IsHighlighted"
                         Value="true" />
              <Condition Property="JournalEntryUnifiedViewConverter.JournalEntryPosition"
                         Value="Forward" />
            </MultiTrigger.Conditions>
            <Setter TargetName="Glyph"
                    Property="Data"
                    Value="M 3 1 L 7 5 L 3 9 z" />
            <Setter TargetName="Glyph"
                    Property="Stroke"
                    Value="{x:Null}" />
            <Setter TargetName="Glyph"
                    Property="Fill">
              <Setter.Value>
                <SolidColorBrush Color="{StaticResource GlyphColor}" />
              </Setter.Value>
            </Setter>
          </MultiTrigger>
          <MultiTrigger>
            <MultiTrigger.Conditions>
              <Condition Property="IsHighlighted"
                         Value="true" />
              <Condition Property="JournalEntryUnifiedViewConverter.JournalEntryPosition"
                         Value="Back" />
            </MultiTrigger.Conditions>
            <Setter TargetName="Glyph"
                    Property="Data"
                    Value="M 7 1 L 3 5 L 7 9 z" />
            <Setter TargetName="Glyph"
                    Property="Stroke"
                    Value="{x:Null}" />
            <Setter TargetName="Glyph"
                    Property="Fill">
              <Setter.Value>
                <SolidColorBrush Color="{StaticResource GlyphColor}" />
              </Setter.Value>
            </Setter>
          </MultiTrigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!-- Merges Back and Forward Navigation Stacks -->

<JournalEntryUnifiedViewConverter x:Key="JournalEntryUnifiedViewConverter" />

<!-- SimpleStyles: Frame -->

<Style x:Key="{x:Type Frame}"
       TargetType="{x:Type Frame}">
  <Setter Property="SnapsToDevicePixels"
          Value="true" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Frame}">
        <DockPanel>
          <Border DockPanel.Dock="Top"
                  Height="22"
                  BorderThickness="1">
            <Border.BorderBrush>
              <LinearGradientBrush EndPoint="0.5,1"
                                   StartPoint="0.5,0">
                <GradientStop Color="{DynamicResource BorderLightColor}"
                              Offset="0" />
                <GradientStop Color="{DynamicResource BorderDarkColor}"
                              Offset="1" />
              </LinearGradientBrush>
            </Border.BorderBrush>
            <Grid>
              <Grid.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>

              </Grid.Background>
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="16" />
                <ColumnDefinition Width="*" />
              </Grid.ColumnDefinitions>

              <Menu x:Name="NavMenu"
                    Grid.ColumnSpan="3"
                    Height="16"
                    Margin="1,0,0,0"
                    VerticalAlignment="Center"
                    Style="{StaticResource FrameMenu}">
                <MenuItem Style="{StaticResource FrameHeaderMenuItem}"
                          ItemContainerStyle="{StaticResource FrameSubmenuItem}"
                          IsSubmenuOpen="{Binding (MenuItem.IsSubmenuOpen), 
                  Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
                  <MenuItem.ItemsSource>
                    <MultiBinding Converter="{StaticResource JournalEntryUnifiedViewConverter}">
                      <Binding RelativeSource="{RelativeSource TemplatedParent}"
                               Path="BackStack" />
                      <Binding RelativeSource="{RelativeSource TemplatedParent}"
                               Path="ForwardStack" />
                    </MultiBinding>
                  </MenuItem.ItemsSource>
                </MenuItem>
              </Menu>

              <Path Grid.Column="0"
                    SnapsToDevicePixels="false"
                    IsHitTestVisible="false"
                    Margin="2,1.5,0,1.5"
                    Grid.ColumnSpan="3"
                    StrokeThickness="1"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Center"
                    Data="M15,14 Q18,12.9 20.9,14 A8.3,8.3,0,0,0,35.7,8.7 A8.3,8.3,0,0,0,
                    25.2,0.6 Q18, 3.3 10.8,0.6 A8.3,8.3,0,0,0,0.3,8.7 A8.3,8.3,0,0,0,15,14 z"
                    Stroke="{x:Null}">
                <Path.Fill>
                  <LinearGradientBrush EndPoint="0.5,1"
                                       StartPoint="0.5,0">
                    <GradientStop Color="{DynamicResource ControlMediumColor}"
                                  Offset="0" />
                    <GradientStop Color="{DynamicResource ControlDarkColor}"
                                  Offset="1" />
                  </LinearGradientBrush>
                </Path.Fill>
              </Path>
              <Button Style="{StaticResource FrameButtonStyle}"
                      Command="NavigationCommands.BrowseBack"
                      Content="M 4 0 L 0 4 L 4 8 Z"
                      Margin="2.7,1.5,1.3,1.5"
                      Grid.Column="0" />
              <Button Style="{StaticResource FrameButtonStyle}"
                      Command="NavigationCommands.BrowseForward"
                      Content="M 4 0 L 0 4 L 4 8 Z"
                      Margin="1.3,1.5,0,1.5"
                      Grid.Column="1" />
            </Grid>
          </Border>
          <Border BorderThickness="1">
            <Border.BorderBrush>
              <SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
            </Border.BorderBrush>
            <ContentPresenter x:Name="PART_FrameCP"
                              Height="458"
                              Width="640" />
          </Border>
        </DockPanel>
        <ControlTemplate.Triggers>
          <MultiTrigger>
            <MultiTrigger.Conditions>
              <Condition Property="CanGoForward"
                         Value="false" />
              <Condition Property="CanGoBack"
                         Value="false" />
            </MultiTrigger.Conditions>
            <Setter TargetName="NavMenu"
                    Property="IsEnabled"
                    Value="false" />
          </MultiTrigger>
        </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/frame-styles-and-templates?view=netframeworkdesktop-4.8 

 

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

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

docs.microsoft.com

 

반응형

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

Frame④  (0) 2022.05.27
Frame③  (0) 2022.05.26
Frame①  (0) 2022.05.25
Expander  (0) 2022.05.20
DocumentViewer  (0) 2022.05.20