WPF

[WPF] WindowChrome 와 Shadow 를 가진 창 만들기 [2/2]

Chanhongv 2024. 10. 11. 11:46

이번 포스팅에는 다음을 진행할 것입니다!~

 1. ControlBox 기능 구현

 2. 최대화시 스타일 조정

 

Control Box 기능은 비하인드 코드에서 진행하도록 하겠습니다.

MVVM 패턴에서 비하인드 코드에 작성하는 것을 허용하지 않는다(?) 라고 하지만

View 자체 기능이라고 생각하여 ViewModel 과 연동은 필요하지 않다고 생각합니다.

 

비하인드에서의 작성은 너무 쉽고 간단하기때문에 능률도 올릴 수 있습니다.

 

1. ControlBox 기능 구현

     <Button Grid.Column="1"
             Style="{StaticResource ControlBoxButtonStyle}"
             Content="🗕" 
             Click="MinimizeButton_Click"/>
     <Button x:Name="xMaximizeButton"
             Grid.Column="2"
             Style="{StaticResource ControlBoxButtonStyle}"
             Content="🗖"
             Click="MaximizeButton_Click"/>
     <Button Grid.Column="3"
             Style="{StaticResource ControlBoxButtonStyle}"
             Content="🗙"
             Click="ExitButton_Click"/>
             
             
 private void MinimizeButton_Click(object sender, RoutedEventArgs e)
 {
     WindowState = WindowState.Minimized;
 }
 private void MaximizeButton_Click(object sender, RoutedEventArgs e)
 {
  if (WindowState == WindowState.Maximized)
  {
      WindowState = WindowState.Normal;
  }
  else
  {
      WindowState = WindowState.Maximized;
  }
 }
 private void ExitButton_Click(object sender, RoutedEventArgs e)
 {
     Application.Current.Shutdown();
 } private void MinimizeButton_Click(object sender, RoutedEventArgs e)
 {
     WindowState = WindowState.Minimized;
 }
 private void MaximizeButton_Click(object sender, RoutedEventArgs e)
 {
     if (WindowState == WindowState.Maximized)
     {
         xMaximizeButton.Content = "🗖";
         WindowState = WindowState.Normal;
     }
     else
     {
         xMaximizeButton.Content = "🗗";
         WindowState = WindowState.Maximized;
     }
 }
 private void ExitButton_Click(object sender, RoutedEventArgs e)
 {
     Application.Current.Shutdown();
 }

 

 

2. 최대화시 스타일 조정

    public MainWindow()
    {
        InitializeComponent();

        MaxHeight = SystemParameters.WorkArea.Height + 7;
        StateChanged += MainWindow_StateChanged;
    }
    
  private void MainWindow_StateChanged(object? sender, EventArgs e)
  {
      if(WindowState == WindowState.Maximized)
      {
          xMaximizeButton.Content = "🗗";
          xOuterBorder.Margin = new Thickness(7,0,7,0);
          xOuterBorder.CornerRadius = new CornerRadius(0);
          xInnerBoder.CornerRadius = new CornerRadius(0);

          xWindowChomre.ResizeBorderThickness = new Thickness(0);
      }
      else
      {
          xMaximizeButton.Content = "🗖";
          xOuterBorder.Margin = new Thickness(10);
          xOuterBorder.CornerRadius = new CornerRadius(10);
          xInnerBoder.CornerRadius = new CornerRadius(10);

          xWindowChomre.ResizeBorderThickness = new Thickness(16);
      }
  }

 

 

전체 코드

MainWindow.xaml

<Window x:Class="WindowChorme.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        
        WindowStyle="None"
        AllowsTransparency="True"
        Background="Transparent"
        
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>
        <Style TargetType="{x:Type Button}" x:Key="ControlBoxButtonStyle">
            <Setter Property="Width" Value="40"/>
            <Setter Property="Cursor" Value="Hand"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="border"
                                BorderThickness="0"
                                Background="{TemplateBinding Background}"> 
                            <TextBlock Text="{TemplateBinding Content}"
                                       VerticalAlignment="Center"
                                       HorizontalAlignment="Center"
                                       TextAlignment="Center"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="#EFEFEF"/>
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                    <Condition Property="Content" Value="🗙"/>
                                </MultiTrigger.Conditions>
                                <Setter TargetName="border" Property="CornerRadius" Value="0 10 0 0"/>
                                <Setter Property="Background" Value="#FF0000"/>
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <WindowChrome.WindowChrome>
        <WindowChrome x:Name="xWindowChomre"
                      CaptionHeight="40"
                      GlassFrameThickness="0"
                      ResizeBorderThickness="16"/>
    </WindowChrome.WindowChrome>

    <Border x:Name="xOuterBorder"
            Margin="10"
            CornerRadius="10"
            Background="Transparent">

        <Border.Effect>
            <DropShadowEffect BlurRadius="10"
                              ShadowDepth="4"
                              Opacity="0.5"/>
        </Border.Effect>

        <Border x:Name="xInnerBoder"
                Background="White"
                BorderThickness="2"
                BorderBrush="#B6B6B6"
                CornerRadius="10">
            <Grid Background="Transparent">
                <Grid.RowDefinitions>
                    <RowDefinition Height="40"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>

                <Grid Grid.Row="0">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0"
                               Text="Window Chorme Style Test"
                               VerticalAlignment="Center"
                               Margin="10 0 0 0"/>
                    <Button Grid.Column="1"
                            Style="{StaticResource ControlBoxButtonStyle}"
                            Content="🗕" 
                            Click="MinimizeButton_Click"/>
                    <Button x:Name="xMaximizeButton"
                            Grid.Column="2"
                            Style="{StaticResource ControlBoxButtonStyle}"
                            Content="🗖"
                            Click="MaximizeButton_Click"/>
                    <Button Grid.Column="3"
                            Style="{StaticResource ControlBoxButtonStyle}"
                            Content="🗙"
                            Click="ExitButton_Click"/>
                </Grid>

                <Border Grid.Row="1" Height="6" BorderThickness="0 0.2 0 0">
                    <Border.BorderBrush>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="1, 0">
                            <GradientStop Color="#FFFFFF" Offset="0.0" />
                            <GradientStop Color="#686868" Offset="0.5" />
                            <GradientStop Color="#FFFFFF" Offset="1.0" />
                        </LinearGradientBrush>
                    </Border.BorderBrush>

                    <Border.Background>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="0, 1">
                            <GradientStop Color="#FAFAFA" Offset="0.0" />
                            <GradientStop Color="#FFFFFF" Offset="1.0" />
                        </LinearGradientBrush>
                    </Border.Background>
                </Border>

            </Grid>
        </Border>
    </Border>

</Window>

 

 

MainWindow.xaml.cs

using System.Windows;

namespace WindowChorme
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            MaxHeight = SystemParameters.WorkArea.Height + 7;
            StateChanged += MainWindow_StateChanged;
        }

        private void MinimizeButton_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }
        private void MaximizeButton_Click(object sender, RoutedEventArgs e)
        {
            if (WindowState == WindowState.Maximized)
            {
                WindowState = WindowState.Normal;
            }
            else
            {
                WindowState = WindowState.Maximized;
            }
        }
        private void ExitButton_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void MainWindow_StateChanged(object? sender, EventArgs e)
        {
            if(WindowState == WindowState.Maximized)
            {
                xMaximizeButton.Content = "🗗";
                xOuterBorder.Margin = new Thickness(7,0,7,0);
                xOuterBorder.CornerRadius = new CornerRadius(0);
                xInnerBoder.CornerRadius = new CornerRadius(0);

                xWindowChomre.ResizeBorderThickness = new Thickness(0);
            }
            else
            {
                xMaximizeButton.Content = "🗖";
                xOuterBorder.Margin = new Thickness(10);
                xOuterBorder.CornerRadius = new CornerRadius(10);
                xInnerBoder.CornerRadius = new CornerRadius(10);

                xWindowChomre.ResizeBorderThickness = new Thickness(16);
            }
        }
    }
}

 

WindowStyle = Normal

 

WindowStyle = Maximize