public ref class WindowChrome : System::Windows::Freezable
public class WindowChrome : System.Windows.Freezable
type WindowChrome = class
    inherit Freezable
Public Class WindowChrome
Inherits Freezable
WindowChrome

通过该 WindowChrome 类,可以将Windows Presentation Foundation (WPF) 内容扩展到通常为操作系统的窗口管理器保留的窗口的非工作区。

标准Windows

标准窗口由两个重叠的矩形组成。 外部矩形是 非工作区 ,通常称为 部件版式 。 它由操作系统的窗口管理器绘制和管理。 其维度由标准操作系统设置确定。 非客户端框架提供标准窗口功能和行为。 其中包括标题按钮 (最小化、最大化和关闭) 、窗口边框、调整大小和移动行为、应用程序图标和标题以及系统菜单。 内部矩形是 工作区 。 它包含应用程序的内容,并由应用程序绘制和管理。 有关 WPF 应用程序中的窗口的详细信息,请参阅 WPF Windows概述 。

下图显示了标准窗口的各个部分。

自定义Windows

可以通过将 Window.WindowStyle 属性 None 设置为或使用 WindowChrome 类来自定义窗口边框。

WindowStyle.None

自定义 WPF 应用程序窗口外观的一种方法是将 Window.WindowStyle 属性 None 设置为 。 这会从窗口中删除非客户端框架,并仅保留可以向其应用自定义样式的工作区。 但是,删除非客户端帧时,也会丢失它提供的系统功能和行为,例如标题按钮和窗口大小调整。 另一个副作用是,窗口将在最大化时覆盖Windows任务栏。 通过设置 WindowStyle.None ,可以创建完全自定义的应用程序,但也要求在应用程序中实现自定义逻辑以模拟标准窗口行为。

WindowChrome

若要在保留其标准功能时自定义窗口,可以使用该 WindowChrome 类。 该 WindowChrome 类将窗口框架的功能与视觉对象分开,并允许你控制应用程序窗口的客户端和非客户端区域之间的边界。 通过 WindowChrome 该类,可以通过扩展工作区来覆盖非工作区,将 WPF 内容置于窗口框架中。 同时,它通过两个不可见区域保留系统行为: 调整边框 和 标题 区域的大小。

使用类创建自定义窗口 WindowChrome 有两个主要部分。 首先,通过设置对象上公开 WindowChrome 的属性来自定义窗口的非客户端部分。 然后,为窗口提供一个模板,用于定义扩展到非工作区的应用程序部分。 对象上 WindowChrome 公开的属性是 ResizeBorderThickness 、 CaptionHeight 和 CornerRadius GlassFrameThickness 。

该 ResizeBorderThickness 属性指定应用程序窗口外部的不可见边框,用户可以单击并拖动以调整窗口的大小。

该 CaptionHeight 属性指定窗口顶部的一个不可见区域,该区域启用通常与标题栏关联的系统行为。 这些行为包括:单击并拖动以移动窗口,双击以最大化窗口,右键单击以显示系统菜单。

调整边框和标题区域的大小没有任何视觉元素;它们仅定义响应输入并启用标准系统提供的窗口行为的区域。

该 CornerRadius 属性指定圆角窗口的圆角量。 如果为窗口启用了玻璃框架,则此属性没有任何影响。

该 GlassFrameThickness 属性指定窗口周围的玻璃框架的宽度。 默认情况下,它使用属性指定的 WindowNonClientFrameThickness 系统值来模拟标准窗口的外观。 使用玻璃框架时,“最小化”、“最大化”和“关闭”的标题按钮可见且交互。 应用程序负责显示应用程序图标和标题文本。 可以将属性设置为 GlassFrameThickness 使玻璃框架比默认值更宽或更窄。

更改属性时 GlassFrameThickness 标题按钮的大小不会更改。 如果玻璃框架顶部的高度小于标题按钮的高度,标题按钮将不会完全可见。

若要使没有玻璃框架的自定义窗口,请将 GlassFrameThickness 属性设置为统一值 0。 这将禁用和隐藏标准标题按钮。

若要扩展玻璃框架以覆盖整个窗口,请将 GlassFrameThickness 属性设置为任意一端的负值。 当属性 GlassFrameThickness 设置为任何一端的负值时,其强制值将等于 GlassFrameCompleteThickness 。

Aero 是Windows Vista 中引入Windows桌面的外观和功能的一组视觉增强功能。 航空更直观地明显特征之一是半透明玻璃窗边框。 Windows Aero 由桌面窗口管理器的桌面组合功能 (DWM) 启用。

Windows航空玻璃效果在所有操作系统上不受支持,并且可以在受支持的操作系统上禁用。 如果 Windows Aero 不可用,则无论属性值如何 GlassFrameThickness ,都不会显示玻璃框架。 此属性指定的边框区域将改为显示为黑色。 IsGlassEnabled 检查该属性以验证Windows航空玻璃效果是否可用。 如果玻璃效果不可用,则应提供一个不使用玻璃框架的备用窗口样式,或者通过将窗口样式设置为 null 来使用标准窗口。

通过指定一个 ControlTemplate 来定义框架内容的外观和行为,将 WPF 内容扩展到窗口框架。 将 ControlTemplate 的 TargetType 设置为要自定义的窗口的类型。

<ControlTemplate TargetType="{x:Type local:MainWindow}">  

默认情况下,窗口非工作区内的任何视觉元素部分不交互。 若要在非工作区中启用交互式元素,请将 WindowsChrome.IsHitTestVisibleInChrome 附加属性附加到元素,并将其设置为 true。

以下 XAML 标记显示了使用 WindowChrome 类自定义窗口所需的主要元素。

<Style x:Key="StandardStyle" TargetType="{x:Type local:MainWindow}">  
    <Setter Property="shell:WindowChrome.WindowChrome">  
        <Setter.Value>  
            <shell:WindowChrome />  
        </Setter.Value>  
    </Setter>  
    <Setter Property="Template">  
        <Setter.Value>  
            <ControlTemplate TargetType="{x:Type local:MainWindow}">  
                    <Border Background="White"  
                            Margin="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=WindowNonClientFrameThickness}">  
                        <ContentPresenter Content="{TemplateBinding Content}" />  
                    </Border>  
                    <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}"   
                               VerticalAlignment="Top" HorizontalAlignment="Left"   
                               Margin="36,8,0,0"/>  
                    <Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Icon}"  
                           VerticalAlignment="Top" HorizontalAlignment="Left"  
                           Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(shell:WindowChrome.WindowChrome).ResizeBorderThickness}"   
                           Width="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=SmallIconSize.Width}"  
                           shell:WindowChrome.IsHitTestVisibleInChrome="True"/>  
                </Grid>  
            </ControlTemplate>  
        </Setter.Value>  
    </Setter>  
</Style>  

第一个 setter 将 WindowChrome 附加到窗口。 它使用 WindowChrome 属性的所有默认值,这使得窗口看起来像标准窗口。

<Setter Property="shell:WindowChrome.WindowChrome">  
    <Setter.Value>  
        <shell:WindowChrome />  
    </Setter.Value>  
</Setter>  

窗口模板必须指定内容演示者才能显示应用程序中指定的窗口的内容。 默认情况下,WindowChrome 类扩展了工作区以覆盖非客户端边框。 若要发现玻璃框架,需要指定 ContentPresenter 周围的边距。 此标记指定内容演示者周围有白色背景的边框,以模拟标准窗口的外观。 它还指定绑定到 WindowNonClientFrameThickness 属性的边距,该属性获取帧的默认系统宽度。

<Border Background="White"  
    Margin="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=WindowNonClientFrameThickness}">  
    <ContentPresenter Content="{TemplateBinding Content}" />  
</Border>  

WindowChrome 类不显示应用程序图标和标题;它们必须作为自定义内容添加到边框。 以下 XAML 添加图像和文本块以显示图标和标题。 这两个元素都绑定到窗口上的相应属性。 图像宽度绑定到 SmallIconSize 宽度,该宽度获取图标的默认系统大小。 IsHitTestVisibleInChrome 附加属性在图像上设置,以便它可以接收鼠标事件。

<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Icon}"  
       VerticalAlignment="Top" HorizontalAlignment="Left"  
       Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(shell:WindowChrome.WindowChrome).ResizeBorderThickness}"   
       Width="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=SmallIconSize.Width}"  
       shell:WindowChrome.IsHitTestVisibleInChrome="True"/>  
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}"   
           VerticalAlignment="Top" HorizontalAlignment="Left"   
           Margin="36,8,0,0"/>  
		  

对指定依赖属性的值进行强制。 通过对调用方 DependencyObject 上存在的依赖属性的属性元数据中所指定的任何 CoerceValueCallback 函数进行调用来完成此操作。

(继承自 DependencyObject)

重写 OnPropertyChanged(DependencyPropertyChangedEventArgs) 的 DependencyObject 实现,以同时调用任何响应类型 Freezable 不断变化的依赖属性的 Changed 处理程序。

(继承自 Freezable)

引发 Freezable 的 Changed 事件并调用其 OnChanged() 方法。 从 Freezable 派生的类应在修改的类成员不存储为依赖属性的任何 API 的末尾调用此方法。

(继承自 Freezable)

验证 Freezable 是否未被冻结,并且是否正在从有效的线程上下文中访问它。 Freezable 的继承项应当在任何 API 一开始写入不属于依赖项属性的数据成员时调用此方法。

(继承自 Freezable)