概述
在WPF界面开发中,系统默认的窗口比较丑,有时候想自定义窗体,比如微信的客户端窗口这样:使得左边的一块顶到最上端,如下图所示:
这时候我们可以 WindowStyle="None",AllowsTransparency="True"去掉默认的窗体边框,然后添加最小最大和关闭的按钮,然后重写相关的功能实现
<TextBlock x:Name="lblTitle" Text="自定义窗体" Foreground="White" FontSize="14" Margin="10 0 0 0" VerticalAlignment="Center"/><StackPanel Orientation="Horizontal" HorizontalAlignment="Right"><Button WindowChrome.IsHitTestVisibleInChrome="True" Name="button_MiniSize" Content="─" Style="{StaticResource btn_nap}" HorizontalAlignment="Right" Foreground="White" Margin="0 0 5 0" Height="30" Width="30"/><Button WindowChrome.IsHitTestVisibleInChrome="True" Name="button_MaxSize" Content="☐" Style="{StaticResource btn_nap}" HorizontalAlignment="Right" Foreground="White" Margin="0 0 5 0" Height="30" Width="30"/><Button WindowChrome.IsHitTestVisibleInChrome="True" x:Name="btn_Close" Content="✕" Style="{StaticResource btn_nap}" HorizontalAlignment="Right" Foreground="White" Margin="0 0 5 0" Height="30" Width="30"/></StackPanel>
但是这样做的话,这就不贴近原生窗口体验了,
-. 需要写大量代码实现Window本来的拖动、改变大小、最大化最小化等行为;
-. 各种其它细节的修改,比如:最大化会覆盖任务栏等;
为了保持最大的原生的同时以少量代码实现自定义窗体,我们使用WindowChrome去实现会更加便捷和优雅.
WindowChrome用法举例
<Window x:Class="WpfApp13.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:WpfApp13"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800" Background="{x:Null}" FontWeight="ExtraLight" ResizeMode="CanResize" WindowStartupLocation="CenterScreen"><Window.Style><Style TargetType="Window"><Setter Property="WindowChrome.WindowChrome"><Setter.Value><WindowChromeCornerRadius="0"CaptionHeight="30"GlassFrameThickness="-1"UseAeroCaptionButtons="True"NonClientFrameEdges="None"/></Setter.Value></Setter>
</Style></Window.Style><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="Auto"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Image Source="left1.png" Stretch="Fill"/><Grid Grid.Column="1" ><Grid.RowDefinitions><RowDefinition Height="40"/><RowDefinition Height="32"/><RowDefinition Height="*"/></Grid.RowDefinitions><Grid Grid.Row="0" ><Menu Margin="2,8,200,0" VerticalAlignment="Center" WindowChrome.IsHitTestVisibleInChrome="True" Background="Transparent"><MenuItem Header="C#技术交流⑥群(111)" FontSize="15" /></Menu></Grid><Grid Grid.Row="2"><TextBlockHorizontalAlignment="Center"VerticalAlignment="Center"FontSize="50"FontWeight="Bold"Foreground="blue"Text="呆萌气质小可爱" /></Grid></Grid></Grid>
</Window>
运行结果:
WindowChrome用法说明
UseAeroCaptionButtons:表示标题栏上的那三个默认按钮是否可以命中,这里设置为true,如果要自己管理则设置为false。
GlassFrameThickness和ResizeBorderThickness:这两个属性用于控制边框,及用户可以单击并拖动以调整窗口大小的区域的宽度;其中GlassFrameThickness用来设置距离区域的厚度,设置为-1,可以使得区域覆盖整个界面;ResizeBorderThickness可以设置窗口缩放的边框厚度,不宜设置过大。
CaptionHeight:指定WindowChrome的标题栏高度;我这里设置的是30。设置为0表示界面无法响应鼠标的任何操作(拖动窗口, 双击标题栏的最大化最小化。。。仅仅是行为区域,并不影响外观)。
NonClientFrameEdges:即指定哪一边不属于客户区。用法举例:
<WindowChrome.WindowChrome><WindowChrome NonClientFrameEdges="Left,Bottom,Right" />
</WindowChrome.WindowChrome>
要使用WindowChrome,最简洁语法如下:
<WindowChrome.WindowChrome><WindowChrome /></WindowChrome.WindowChrome>
然后得到的窗体拥有默认窗口的所有窗口行为,
此外需要注意的是,如果元素在CaptionHeight的高度内,是无法响应鼠标事件的,此时需要给元素设置属性WindowChrome.IsHitTestVisibleInChrome="True",很常见的问题,在自定义标题按钮的时候,会发现自己点击不了标题按钮!
源码下载
链接:https://pan.baidu.com/s/1ilUXW3JzrCLQX2xFINmByw
提取码:6666