导读
背景
WPF有两种主流的自定义Window窗体的方案,都各有缺点。
方法一、缺点
《WPF编程宝典》介绍了使用WindowStyle="None"
和AllowsTransparency="True"
创建无边框。
这种方法的原理是从Window中删除non-client area(即chrome,包括 标题栏和frame),再由用户自定义Window的所有外观和部分行为。这种方式的自由度很高,但也有不少问题:
- Window没有阴影导致很难看,但添加自定义的DropShadowEffect又十分影响性能;
- 没有弹出、关闭、最大化、最小化动画,尤其当启动了大量任务将任务栏堆满的情况下没有最小化动画很容易找不到自己的程序;
- 没有动画很麻烦,自定义的动画做得不好也十分影响使用;
- 需要写大量代码实现Window本来的拖动、改变大小、最大化等行为;
- 各种其它细节的缺失;
- 渲染新能差
大部分自定义Window或多或少都有上面所说的问题,幸好WPF提供了WindowChrome这个类用于创建自定义的Window,这个类本身处理了上面部分问题。请相信阅读WindowChrome的功能详解,在来看这篇文章。
方法二、缺点
单纯的使用WindowChrome,失去灵活性,WindowChrome本身有bug。
因此考虑将两种方法结合起来使用,保留两种方法的部分优点。
自定义WPF窗体
采用WindowChrome +WindowStyle="None"
和AllowsTransparency="True"
创建WPF窗体。
功能:
1、标题栏:拖拽、系统菜单(WindowChrome的功能)
2、边框功能:调整边框(WindowChrome的功能)、边框阴影(要自定义)
去掉window默认样式
WindowStyle="None" AllowsTransparency="True"
包括去掉标题栏功能(最大化按钮、最小化按钮、关闭按钮、系统菜单、拖拽)、边框功能(调整、阴影)
<Window x:Class="CustomerWindowWithWindowChromeDemo.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:CustomerWindowWithWindowChromeDemo" mc:Ignorable="d" Background="{x:Null}" WindowStartupLocation="CenterScreen" Topmost="True" WindowStyle="None" AllowsTransparency="True" ResizeMode="CanResizeWithGrip" Title="MainWindow" Height="800" Width="1400"> </Window>
添加 窗体【拖拽标题栏】、【系统菜单】、【边框调整】 功能
给窗体添加WindowChrome.WindowChrome附加属性,该附加属性具有窗体标题栏、glassFrame、扩大工作区到整个窗体的功能。
当WindowChrome.GlassFrameThickness=0 时,隐藏了glassFrame(去掉毛玻璃框架最大按钮、最小按钮、关闭按钮)。
剩下标题栏(双击最大化、双击最小化、拖拽、系统菜单)、调整窗体边框功能 、扩大工作区到整个窗体的功能。
<!--GlassFrameThickness=0 去掉毛玻璃框架(最大按钮、最小按钮、关闭按钮)--> <WindowChrome.WindowChrome> <WindowChrome GlassFrameThickness="0"></WindowChrome> </WindowChrome.WindowChrome>
自定义边框阴影
该功能需要自定义,需要修改窗体控件模板(ControlTemplate ),在控件模板中添加两个Border,外层的border起到坐标的作用,为了让内层border的margin起作用,内层border控制阴影和边框样式。效果如下:
样式代码:
<Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Window}"> <!-- 阴影效果:一定要设置Border的Margin ,否制不会出现阴影效果 --> <Border> <Border BorderThickness="1" BorderBrush="#d9d9d9" Background="White" Margin="5" CornerRadius="8"> <Border.Effect> <DropShadowEffect Color="Gray" ShadowDepth="0" BlurRadius="5" Opacity="0.3" Direction="0"/> </Border.Effect> <Grid> <!--其他代码 省略 --> <AdornerDecorator Grid.Row="1"> <ContentPresenter ClipToBounds="True" /> </AdornerDecorator> </Grid> </Border> </Border> </ControlTemplate> </Setter.Value> </Setter>
注意:
AdornerDecorator 为可视化树中的子元素提供 AdornerLayer,如果没有它的话一些装饰效果不能显示(例如下图Button控件的Focus效果),Window的 ContentPresenter 外面套个 AdornerDecorator 是 必不能忘的
WindowChrome 设置效果不理想。所有不采用这种方式了。
标签:自定义,XAML,标题栏,边框,Window,窗体,WindowChrome From: https://www.cnblogs.com/cdaniu/p/16877700.html