より良いエンジニアを目指して

記事を頻繁に書き直す性格なのでごめんなさい。

WindowChromeでキャプションバーなしのウインドウを作る

最近のアプリケーションはキャプションバーがありません。

f:id:rimever:20191123214651p:plain

WPFでは、WindowChromeを使えば出来ます。

docs.microsoft.com

さっと書けないので自分用のメモ。

XAML

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        d:DataContext="{d:DesignInstance local:MainWindowViewModel}"
        Title="MainWindow" Height="350" Width="525" SnapsToDevicePixels="True">
    <Window.Resources>
        <Style x:Key="CaptionButtonStyleKey" TargetType="{x:Type Button}">
            <Setter Property="OverridesDefaultStyle" Value="True" />
            <Setter Property="Foreground" Value="Black" />
            <Setter Property="FontFamily" Value="Marlett"/>
            <Setter Property="IsTabStop" Value="False"/>
            <Setter Property="HorizontalContentAlignment" Value="Center" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="Margin" Value="2" />
            <Setter Property="Padding" Value="1" />
            <Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="border" Background="Transparent" SnapsToDevicePixels="True">
                            <Border.Effect>
                                <DropShadowEffect Opacity="0"/>
                            </Border.Effect>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="0.6"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.ShadowDepth)" Storyboard.TargetName="border">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.Color)" Storyboard.TargetName="border">
                                                <EasingColorKeyFrame KeyTime="0" Value="White"/>
                                            </ColorAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.Opacity)" Storyboard.TargetName="border">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="0.6"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled"/>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <ContentPresenter x:Name="contentPresenter" Focusable="False" Margin="{TemplateBinding Padding}"
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        </Style>
    </Window.Resources>
    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="{x:Static SystemParameters.CaptionHeight}"
                      ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
    </WindowChrome.WindowChrome>
    <Border BorderBrush="Gray"
            BorderThickness="1">
        <Grid>
            <StackPanel Orientation="Horizontal" Margin="5"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Top">
                <Button Content="0" Style="{DynamicResource CaptionButtonStyleKey}" Click="ClickWindowMinimize"/>
                <Button Content="1" Style="{DynamicResource CaptionButtonStyleKey}" Click="ClickWindowMaximize"/>
                <Button Content="2" Style="{DynamicResource CaptionButtonStyleKey}" Click="ClickWindowNormal"/>
                <Button Content="r" Style="{DynamicResource CaptionButtonStyleKey}" Click="ClickClose" />
            </StackPanel>
        </Grid>
    </Border>
</Window>

ビハインドコード xaml.cs

#region

using System.Windows;

#endregion

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // ViewModel
            DataContext = new MainWindowViewModel(); 
            MouseLeftButtonDown += (sender, e) => DragMove();
        }

        private void ClickClose(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void ClickWindowMinimize(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }

        private void ClickWindowMaximize(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Maximized;
        }

        private void ClickWindowNormal(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Normal;
        }
    }
}

f:id:rimever:20191123221911p:plain

参考記事

grabacr.net