WPF带阴影的无边框窗体

使用Window的WindowChrome属性保留无边框窗体的阴影效果、标题栏的双击、标题栏的拖拽事件
标题栏关闭按钮区别于最小化、最大化、恢复按钮样式,先BasedOn="{StaticResource WindowButtonStyle}",然后使用不同MouseOver后的背景色,注意关闭按钮中Path中的DataTrigger的使用

关闭按钮


<Button Name="Close"
Command="SystemCommands.CloseWindowCommand"
IsTabStop="True">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource WindowButtonStyle}">
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="#e81123"/>
        </Trigger>
    </Style.Triggers>
</Style>
</Button.Style>
<Path Width="11" Height="11" Stretch="Fill"
  Data="M681.92382811 547.06835938c0 23.09765625-18.7734375 41.87109375-41.92382813 41.87109375s-41.87109375-18.72070313-41.87109375-41.87109375V183.88671875c0-23.09765625 18.7734375-41.87109375 41.87109375-41.87109375s41.92382813 18.7734375 41.92382813 41.87109375V547.06835938z M288.99999998 531.24804688c0-125.296875 66.18164063-235.45898438 165.21679689-297.15820313 19.35351563-12.33984375 45.24609375-6.43359375 57.48046873 13.18359375 12.234375 19.66992188 6.328125 45.40429689-13.23632812 57.63867188-75.46289063 47.40820313-125.61328125 130.72851563-125.61328125 226.23046874C373.16406248 678.640625 492.44921873 797.97851563 639.99999998 798.29492188c147.55078125-0.36914063 266.78320313-119.70703125 267.046875-267.15234376 0-97.76953125-52.734375-182.8828125-131.25585938-229.60546874-19.93359375-11.8125-26.47265625-37.546875-14.71289062-57.48046876 11.86523438-19.88085938 37.59960938-26.41992188 57.53320313-14.66015625 102.9375 60.80273438 172.49414063 173.1796875 172.49414062 301.64062501 0 193.74609375-157.09570313 350.89453125-350.94726564 350.89453124-194.00976563 0.31640625-351.15820313-156.77929689-351.15820311-350.68359374">
<Path.Style>
    <Style TargetType="Path">
        <Setter Property="Fill" Value="Black"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" Value="True">
                <Setter Property="Fill" Value="White"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Path.Style>
</Path>
</Button>

完整的XAML


<Window x:Class="Chromeless.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:Chromeless"
        mc:Ignorable="d"
        ResizeMode="CanResizeWithGrip"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <Style x:Key="WindowButtonStyle" TargetType="Button">
            <Setter Property="Width" Value="40" />
            <Setter Property="Height" Value="30" />
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border
                            Width="{TemplateBinding Width}"
                            Height="{TemplateBinding Height}"
                            Background="{TemplateBinding Background}">
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="#15333333" />
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Opacity" Value="0.8" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Window.Style>
        <Style TargetType="Window">
            <Setter Property="WindowChrome.WindowChrome">
                <Setter.Value>
                    <WindowChrome CaptionHeight="40" 
                                  ResizeBorderThickness="0" 
                                  UseAeroCaptionButtons="False"/>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Window">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                SnapsToDevicePixels="True">
                            <Grid Margin="{TemplateBinding Padding}">
                                <AdornerDecorator>
                                    <ContentPresenter />
                                </AdornerDecorator>
                                <ResizeGrip Name="ResizeGrip"
                                            Margin="0 0 2 2"
                                            HorizontalAlignment="Right"
                                            VerticalAlignment="Bottom"
                                            IsTabStop="False"
                                            Visibility="Collapsed"
                                            WindowChrome.ResizeGripDirection="BottomRight"/>
                                <StackPanel Height="40"
                                            Margin="0 0 10 0"
                                            HorizontalAlignment="Right"
                                            VerticalAlignment="Top"
                                            Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True">
                                    <Button Name="Minimize" Style="{StaticResource WindowButtonStyle}"
                                            Command="SystemCommands.MinimizeWindowCommand"
                                            IsTabStop="True">
                                        <Path Width="11" Height="2" Stretch="Fill" 
                                              Fill="Black" Data="F1M0,6L0,9 9,9 9,6 0,6z"/>
                                    </Button>
                                    <Button Name="Maximize" Style="{StaticResource WindowButtonStyle}"
                                            Command="SystemCommands.MaximizeWindowCommand"
                                            IsTabStop="True">
                                        <Path Width="11" Height="11" Stretch="Fill"
                                              Fill="Black" Data="M255.488 768.512V403.456l365.568 365.056zM768.512 620.544L403.456 255.488h365.056z"/>
                                    </Button>
                                    <Button Name="Restore" Style="{StaticResource WindowButtonStyle}"
                                            Command="SystemCommands.RestoreWindowCommand"
                                            IsTabStop="True">
                                        <Path Width="11" Height="11" Stretch="Fill"
                                              Fill="Black" Data="F1M0,10L0,3 3,3 3,0 10,0 10,2 4,2 4,3 7,3 7,6 6,6 6,5 1,5 1,10z M1,10L7,10 7,7 10,7 10,2 9,2 9,6 6,6 6,9 1,9z"/>
                                    </Button>
                                    <Button Name="Close"
                                            Command="SystemCommands.CloseWindowCommand"
                                            IsTabStop="True">
                                        <Button.Style>
                                            <Style TargetType="Button" BasedOn="{StaticResource WindowButtonStyle}">
                                                <Style.Triggers>
                                                    <Trigger Property="IsMouseOver" Value="True">
                                                        <Setter Property="Background" Value="#e81123"/>
                                                    </Trigger>
                                                </Style.Triggers>
                                            </Style>
                                        </Button.Style>
                                        <Path Width="11" Height="11" Stretch="Fill"
                                              Data="M681.92382811 547.06835938c0 23.09765625-18.7734375 41.87109375-41.92382813 41.87109375s-41.87109375-18.72070313-41.87109375-41.87109375V183.88671875c0-23.09765625 18.7734375-41.87109375 41.87109375-41.87109375s41.92382813 18.7734375 41.92382813 41.87109375V547.06835938z M288.99999998 531.24804688c0-125.296875 66.18164063-235.45898438 165.21679689-297.15820313 19.35351563-12.33984375 45.24609375-6.43359375 57.48046873 13.18359375 12.234375 19.66992188 6.328125 45.40429689-13.23632812 57.63867188-75.46289063 47.40820313-125.61328125 130.72851563-125.61328125 226.23046874C373.16406248 678.640625 492.44921873 797.97851563 639.99999998 798.29492188c147.55078125-0.36914063 266.78320313-119.70703125 267.046875-267.15234376 0-97.76953125-52.734375-182.8828125-131.25585938-229.60546874-19.93359375-11.8125-26.47265625-37.546875-14.71289062-57.48046876 11.86523438-19.88085938 37.59960938-26.41992188 57.53320313-14.66015625 102.9375 60.80273438 172.49414063 173.1796875 172.49414062 301.64062501 0 193.74609375-157.09570313 350.89453125-350.94726564 350.89453124-194.00976563 0.31640625-351.15820313-156.77929689-351.15820311-350.68359374">
                                            <Path.Style>
                                                <Style TargetType="Path">
                                                    <Setter Property="Fill" Value="Black"/>
                                                    <Style.Triggers>
                                                        <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" Value="True">
                                                            <Setter Property="Fill" Value="White"/>
                                                        </DataTrigger>
                                                    </Style.Triggers>
                                                </Style>
                                            </Path.Style>
                                        </Path>
                                    </Button>
                                </StackPanel>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="WindowState" Value="Maximized">
                                <Setter TargetName="Maximize" Property="Visibility" Value="Collapsed" />
                                <Setter TargetName="Restore" Property="Visibility" Value="Visible" />
                            </Trigger>
                            <Trigger Property="WindowState" Value="Normal">
                                <Setter TargetName="Maximize" Property="Visibility" Value="Visible" />
                                <Setter TargetName="Restore" Property="Visibility" Value="Collapsed" />
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="ResizeMode" Value="CanResizeWithGrip" />
                                    <Condition Property="WindowState" Value="Normal" />
                                </MultiTrigger.Conditions>
                                <Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Style>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="180"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid Background="#303030" WindowChrome.IsHitTestVisibleInChrome="True"/>
        <Grid Column="1">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="40"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid Row="1" Background="#e3efff">

                </Grid>
            </Grid>
        </Grid>
    </Grid>
</Window>

完整的C#代码


using System.Windows;
using System.Windows.Input;

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

            this.CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, OnCloseWindow));
            this.CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, OnMaximizeWindow, OnCanResizeWindow));
            this.CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, OnMinimizeWindow, OnCanMinimizeWindow));
            this.CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, OnRestoreWindow, OnCanResizeWindow));
        }

        private void OnCanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.ResizeMode != ResizeMode.NoResize;
        }

        private void OnMinimizeWindow(object sender, ExecutedRoutedEventArgs e)
        {
            SystemCommands.MinimizeWindow(this);
        }

        private void OnCanResizeWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.ResizeMode == ResizeMode.CanResize || this.ResizeMode == ResizeMode.CanResizeWithGrip;
        }

        private void OnMaximizeWindow(object sender, ExecutedRoutedEventArgs e)
        {
            SystemCommands.MaximizeWindow(this);
        }

        private void OnRestoreWindow(object sender, ExecutedRoutedEventArgs e)
        {
            SystemCommands.RestoreWindow(this);
        }

        private void OnCloseWindow(object sender, ExecutedRoutedEventArgs e)
        {
            SystemCommands.CloseWindow(this);
        }
    }
}

运行效果展示


源码地址


http://hub.dbugs.work/linxmouse/GettingStarted/src/master/WPFChromeless

原文地址:https://www.cnblogs.com/linxmouse/p/13970617.html