使用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