创建WPF项目,记得把“将解决方案和项目放在同一目录中”给取消掉,因为后续有其他同级项目。

自定义窗口第一步当然是干掉默认的窗口样式啦,Win11简单的设置WindowChrome就可以了,但我印象中Win10要复杂点,不过我懒得开Win10看了,要是不对就自己上网查吧。
<WindowChrome.WindowChrome><WindowChrome CaptionHeight="48" UseAeroCaptionButtons="False" CornerRadius="8"/>
</WindowChrome.WindowChrome>
特别注意的是,用这个办法取消窗口固定样式会有一个小毛病————窗口最大化时会有一部分超出屏幕,解决的办法是给最外层的Grid容器添加触发器:
<Style x:Key="WindowContentGridStyle" TargetType="Grid"><Setter Property="Background" Value="#333"/><Style.Triggers><!--最大化时会有一部分超出屏幕--><DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor},Path=WindowState}" Value="{x:Static WindowState.Maximized}"><Setter Property="Margin" Value="7"/></DataTrigger></Style.Triggers>
</Style>
设置完WindowChrome后,右上角那三个按钮会被窗口里的内容盖住,最好重新写三个按钮覆盖在上边,这是我写的样式,参考一下。
<Style x:Key="WindowTopButtonBaseStyle" TargetType="Button"><Setter Property="Height" Value="30"/><Setter Property="Width" Value="45"/><Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/><Setter Property="Background" Value="#01FFFFFF"/><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="#33FFFFFF"/></Trigger></Style.Triggers>
</Style>
<Style x:Key="WindowMinButtonStyle" TargetType="Button" BasedOn="{StaticResource WindowTopButtonBaseStyle}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><Grid Background="{TemplateBinding Background}"><Path Data="M0,0 12,0" Stroke="#efefef" StrokeThickness="2"StrokeEndLineCap="Round" StrokeStartLineCap="Round"HorizontalAlignment="Center" VerticalAlignment="Center"/></Grid></ControlTemplate></Setter.Value></Setter>
</Style>
<Style x:Key="WindowMaxButtonStyle" TargetType="Button" BasedOn="{StaticResource WindowTopButtonBaseStyle}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><Grid Background="{TemplateBinding Background}"><Path Data="M0,0 12,0 12,10 0,10 z" Stroke="#efefef" StrokeThickness="1.5"StrokeEndLineCap="Round" StrokeStartLineCap="Round"HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="path"/></Grid><ControlTemplate.Triggers><DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor},Path=WindowState}" Value="{x:Static WindowState.Maximized}"><Setter TargetName="path" Property="Data" Value="M0,3 0,12 9,12 9,3 z M3,3 3,0 12,0 12,9 9,9"/></DataTrigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style>
<Style x:Key="WindowCloseButtonStyle" TargetType="Button" BasedOn="{StaticResource WindowTopButtonBaseStyle}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><Grid Background="{TemplateBinding Background}"><Path Data="M0,0 12,12 M12,0 0,12" Stroke="#efefef" StrokeThickness="1.5"StrokeEndLineCap="Round" StrokeStartLineCap="Round"HorizontalAlignment="Center" VerticalAlignment="Center"/></Grid></ControlTemplate></Setter.Value></Setter>
</Style>
接下来调用一下就可以了。
最后贴一下全部的代码,从这里往下都不需要看了。
ButtonStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><!--#region 窗口按钮--><Style x:Key="WindowTopButtonBaseStyle" TargetType="Button"><Setter Property="Height" Value="30"/><Setter Property="Width" Value="45"/><Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/><Setter Property="Background" Value="#01FFFFFF"/><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="#33FFFFFF"/></Trigger></Style.Triggers></Style><Style x:Key="WindowMinButtonStyle" TargetType="Button" BasedOn="{StaticResource WindowTopButtonBaseStyle}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><Grid Background="{TemplateBinding Background}"><Path Data="M0,0 12,0" Stroke="#efefef" StrokeThickness="2"StrokeEndLineCap="Round" StrokeStartLineCap="Round"HorizontalAlignment="Center" VerticalAlignment="Center"/></Grid></ControlTemplate></Setter.Value></Setter></Style><Style x:Key="WindowMaxButtonStyle" TargetType="Button" BasedOn="{StaticResource WindowTopButtonBaseStyle}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><Grid Background="{TemplateBinding Background}"><Path Data="M0,0 12,0 12,10 0,10 z" Stroke="#efefef" StrokeThickness="1.5"StrokeEndLineCap="Round" StrokeStartLineCap="Round"HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="path"/></Grid><ControlTemplate.Triggers><DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor},Path=WindowState}" Value="{x:Static WindowState.Maximized}"><Setter TargetName="path" Property="Data" Value="M0,3 0,12 9,12 9,3 z M3,3 3,0 12,0 12,9 9,9"/></DataTrigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style><Style x:Key="WindowCloseButtonStyle" TargetType="Button" BasedOn="{StaticResource WindowTopButtonBaseStyle}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><Grid Background="{TemplateBinding Background}"><Path Data="M0,0 12,12 M12,0 0,12" Stroke="#efefef" StrokeThickness="1.5"StrokeEndLineCap="Round" StrokeStartLineCap="Round"HorizontalAlignment="Center" VerticalAlignment="Center"/></Grid></ControlTemplate></Setter.Value></Setter></Style><!--#endregion-->
</ResourceDictionary>
GridStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Style x:Key="WindowContentGridStyle" TargetType="Grid"><Setter Property="Background" Value="#333"/><Style.Triggers><!--最大化时会有一部分超出屏幕--><DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor},Path=WindowState}" Value="{x:Static WindowState.Maximized}"><Setter Property="Margin" Value="7"/></DataTrigger></Style.Triggers></Style>
</ResourceDictionary>
MainWindow.xaml
<Window x:Class="LkWork.WPF.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:LkWork.WPF"mc:Ignorable="d" WindowStartupLocation="CenterScreen"Title="MainWindow" Height="640" Width="960"><Window.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/LkWork.WPF;component/Resources/Styles/ButtonStyles.xaml"/><ResourceDictionary Source="pack://application:,,,/LkWork.WPF;component/Resources/Styles/GridStyles.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Window.Resources><WindowChrome.WindowChrome><WindowChrome CaptionHeight="48" UseAeroCaptionButtons="False" CornerRadius="8"/></WindowChrome.WindowChrome><Grid Style="{StaticResource WindowContentGridStyle}"><Border Margin="0 48 0 0"/><StackPanel Panel.ZIndex="999" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top"><Button Style="{StaticResource WindowMinButtonStyle}" Click="Min_Click"/><Button Style="{StaticResource WindowMaxButtonStyle}" Click="Max_Click"/><Button Style="{StaticResource WindowCloseButtonStyle}" Click="Close_Click"/></StackPanel></Grid>
</Window>
MainWindow.xaml.cs
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace LkWork.WPF
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void Close_Click(object sender, RoutedEventArgs e){SystemCommands.CloseWindow(this);}private void Min_Click(object sender, RoutedEventArgs e){SystemCommands.MinimizeWindow(this);}private void Max_Click(object sender, RoutedEventArgs e){if (WindowState == WindowState.Maximized) SystemCommands.RestoreWindow(this);else SystemCommands.MaximizeWindow(this);}}
}
