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自定义控件]?Window(窗体)的UI元素及行为

[WPF自定义控件库]使用WindowChrome自定义RibbonWindow

WPF中使用WindowChrome自定义窗口中遇到的最大化问题

WPF编程,使用WindowChrome实现自定义窗口功能的一种方法。

[原创]c# wpf自定义 任意颜色阴影特效融合winform的探索之路

WPF 创建自定义窗体