C# WPF通过WindowChrome自定义窗体
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# WPF通过WindowChrome自定义窗体相关的知识,希望对你有一定的参考价值。
概述
在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>
<WindowChrome
CornerRadius="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">
<TextBlock
HorizontalAlignment="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
以上是关于C# WPF通过WindowChrome自定义窗体的主要内容,如果未能解决你的问题,请参考以下文章
[WPF自定义控件库]使用WindowChrome自定义RibbonWindow
WPF中使用WindowChrome自定义窗口中遇到的最大化问题
WPF编程,使用WindowChrome实现自定义窗口功能的一种方法。