WPF 应用完全模拟 UWP 的标题栏按钮

本文介绍如何在WPF应用中实现完全模拟UWP原生标题栏按钮的样式,包括最小化、还原、最大化和关闭按钮,并提供自绘标题栏按钮的方法。通过自定义窗口样式和逻辑代码,实现与UWP应用一致的视觉效果,同时讨论了兼容Windows 10之前系统的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WPF 自定义窗口样式有多种方式,不过基本核心实现都是在修改 Win32 窗口样式。然而,Windows 上的应用就应该有 Windows 应用的样子嘛,在保证自定义的同时也能与其他窗口样式保持一致当然能最大程度保证 Windows 操作系统上的体验一致性。

本文将分享一个我自制的标题栏按钮样式,使其与 UWP 原生应用一模一样(同时支持自定义)。


WPF 使用 WindowChrome,在自定义窗口标题栏的同时最大程度保留原生窗口样式(类似 UWP/Chrome) 一文中,我使用 WindowChrome 尽可能将 Windows 原生的窗口机制都用上了,试图完全模拟原生窗口的样式。不过,如果自定义了窗口的背景色,那么标题栏那三大金刚键的背景就显得很突兀。

由于 Win32 原生的方法顶多只支持修改标题栏按钮的背景色,而不支持让标题栏按钮全透明,所以我们只能完全由自己来实现这三个按钮的功能了。

标题栏的四个按钮

一开始我说三个按钮,是因为大家一般都只能看得见三个。但这里说四个按钮,是因为实际实现的时候我们是四个按钮。事实上,Windows 的原生实现也是四颗按钮。

  • 最小化
  • 还原
  • 最大化
  • 关闭

当窗口最小化时,显示还原、最大化和关闭按钮。当窗口普通显示时,显示最小化、最大化和关闭按钮,这也是我们见的最多的情况。当窗口最大化时,显示最小化、还原和关闭按钮。

自绘标题栏按钮

标题栏按钮并不单独存在,所以我直接做了一整个窗口样式。使用此窗口样式,窗口能够模拟得跟 UWP 一模一样。

以下是模拟的效果:

WPF 模拟版本
▲ WPF 模拟版本

UWP 原生版本
▲ UWP 原生版本(为避免说我拿同一个应用附图,我选了微软商店应用对比)

为了使用到这样近乎原生的窗口样式,我们需要两个文件。一个放 XAML 样式,一个放样式所需的逻辑代码。

因为代码很长,所以我把它们放到了最后。

如何使用我制作的原生窗口样式

项目目录结构

当你把我的两份代码文件放入到你的项目中之后,在 App.xaml 中将资源引用即可:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Themes/Window.Universal.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

随后,在 MainWindow 中就可以通过 Style="{StaticResource Style.Window.Universal}" 使用这份样式。

<Window x:Class="Walterlv.Demo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:themes="clr-namespace:Walterlv.Themes"
        Title="Walterlv.Demo.SimulateUwp" Width="800" Height="450"
        Background="#279EDA" Style="{StaticResource Style.Window.Universal}">
    <themes:UniversalWindowStyle.TitleBar>
        <themes:UniversalTitleBar ForegroundColor="White" InactiveForegroundColor="#7FFFFFFF"
                                  ButtonHoverForeground="White" ButtonHoverBackground="#3FFFFFFF"
                                  ButtonPressedForeground="#7FFFFFFF" ButtonPressedBackground="#3F000000" />
    </themes:UniversalWindowStyle.TitleBar>
    <Grid>
        <!-- 在这里添加你的正常窗口内容 -->
    </Grid>
</Window>

当然,我额外提供了 UniversalWindowStyle.TitleBar 附加属性,用于像 UWP 那样定制标题栏按钮的颜色。如果不设置,效果跟 UWP 默认情况下的效果完全一样。

下面是这份样式在 Whitman - Microsoft Store 应用中实际使用的效果,其中的颜色设置就是上面代码中所指定的颜色:

Whitman

附样式代码文件

样式文件 Window.Universal.xaml:

<!-- Window.Universal.xaml -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:themes="clr-namespace:Walterlv.Themes">
    <Style x:Key="Style.Window.Universal" TargetType="Window">
        <Style.Resources>
            <SolidColorBrush x:Key="Brush.TitleBar.Foreground" Color="{
    
    Binding Path=(themes:UniversalWindowStyle.TitleBar).ForegroundColor, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
            <SolidColorBrush x:Key="Brush.TitleBar.InactiveForeground" Color="{
    
    Binding Path=(themes:UniversalWindowStyle.TitleBar).InactiveForegroundColor, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
            <SolidColorBrush x:Key="Brush.TitleBar.ButtonHoverForeground" Color="{
    
    Binding Path=(themes:UniversalWindowStyle.TitleBar).ButtonHoverForeground, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
            <SolidColorBrush x:Key="Brush.TitleBar.ButtonHoverBackground" Color="{
    
    Binding Path=(themes:UniversalWindowStyle.TitleBar).ButtonHoverBackground, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
            <SolidColorBrush x:Key="Brush.TitleBar.ButtonPressedForeground" Color="{
    
    Binding Path=(themes:UniversalWindowStyle.TitleBar).ButtonPressedForeground, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
            <SolidColorBrush x:Key="Brush.TitleBar.ButtonPressedBackground" Color="{
    
    Binding Path=(themes:Univer
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值