1. Windows 11 的圆角

在直角统治了微软的 UI 设计多年以后,微软突然把直角骂了一顿,说还是圆角好看,于是 Windows 11 随处都可看到圆角设计。Windows 11 使用 3 个级别的圆角,具体取决于要应用圆角的 UI 组件及该组件相对于相邻元素的排列方式。

圆角半径 使用情况
8px 窗体、Flyout 、弹出菜单等 。另外,当窗体最大化或使用对齐布局时不应用圆角。
4px 页面内的元素,如按钮或列表等。
0px 与其它直边相交的直边不使用圆角。

也就是说在 Windows 11 上窗体需要应用半径为 8px 的圆角。

2. 处理 WindowChrome 的圆角

对于 WPF,如果使用原生 Window 的话不需要额外处理圆角,如果使用了 WindowChrome 自定义窗体样式的话呢?

结论是,如果自定义的 Window 使用了 1 像素的窄边框或无边框的样式,那就可能不需要额外处理。

下面这两张图是同一个自定义的 Window 分别在 Windows 11 和 10 上的样子:

可以看到这是个模仿 Windows 10 的 Window 样式,边框只有 1 像素。在 Windows 11 里 WindowChrome 会自动裁剪最外层那 1 像素边框和圆角的其它部分,然后补上一条灰色的边框。这做法简单粗暴但有效。被裁剪过后自定义的 Window 成了一个无边框圆角窗口,看着还挺时髦的。

但这个简单裁剪也可能遇到问题,如果 Window 里的内容正好有个直角的元素,而且这个直角还靠着圆角,就可能被裁剪掉;或者自定义的 Window 使用了无边框的样式,那么这个贴边的边框就会被裁剪掉一像素:

所以 Window 可能不需要额外处理,但内容可能需要,这取决于以前的设计。

还有一种情况,如果这个 Window 的边框大于一个像素(像 Windows 8 那样的粗边框),那就需要修改 Window 样式了:

3. 我就是喜欢直的,不想要圆角,怎么办

上图是 Aero2 的主题样式,这是 Windows 8 以后 WPF 程序的默认主题,再之后微软就没有更新过 WPF 的主题。即使在 Windows 11 上,WPF 的主题也没有获得更新。所以,假使现有的 WPF 程序使用了默认主题,或者自定义的主题按照微软一向的审美全使用了直角元素,那到了 Windows 11 上就会显得格格不入。

微软还是很贴心的,如果我们不想更改样式,可以使用 DwmSetWindowAttribute 和 DWM_WINDOW_CORNER_PREFERENCE 控制 Window 的圆角。

using System.Runtime.InteropServices;
using System.Windows.Interop; public partial class MainWindow : Window
{ public MainWindow()
{
InitializeComponent(); IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint)); // ...
// Perform any other work necessary
// ...
} // The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
public enum DWMWINDOWATTRIBUTE
{
DWMWA_WINDOW_CORNER_PREFERENCE = 33
} // The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
// what value of the enum to set.
public enum DWM_WINDOW_CORNER_PREFERENCE
{
DWMWCP_DEFAULT = 0,
DWMWCP_DONOTROUND = 1,
DWMWCP_ROUND = 2,
DWMWCP_ROUNDSMALL = 3
} // Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern long DwmSetWindowAttribute(IntPtr hwnd,
DWMWINDOWATTRIBUTE attribute,
ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
uint cbAttribute); // ...
// Various other definitions
// ...
}

其中 DWM_WINDOW_CORNER_PREFERENCE 枚举值的含义如下:

枚举值 说明
DWMWCP_DEFAULT 让系统决定是否对窗口采用圆角设置。
DWMWCP_DONOTROUND 绝不对窗口采用圆角设置。
DWMWCP_ROUND 适当时采用圆角设置。
DWMWCP_ROUNDSMALL 适当时可采用半径较小的圆角设置。

在 Windows 11 上,使用了上面 4 钟枚举值的窗口效果如下:

4. 最后

关于使用 WindowChrome 自定义窗体的内容,可以参考这几篇文章:

另外,关于圆角我要抱怨一下:

在 Windows 11 中,我们对窗口边框进行了圆角处理。 我们的用户研究团队发现,圆润的几何图形在心理上提供一种安全感,并且使应用的 UI 更易于扫描。 这使用户更少感觉威慑,也使应用更具吸引力。 圆角处理的量也是精心选择的。 我们公司对此进行了研究,努力在专业性、柔和感和吸引度之间取得平衡。

微软的文档这样声称,我是一个字都不信的,难道这么多年来区区 Windows 的直角就让我感觉到威慑和没有安全感了?微软还有比 UWP 更能让我没有安全感的东西?我倒想看看几年后又流行直角时微软要怎么解释。

5. 参考

在 Windows 11 的桌面应用中应用圆角

在 Windows 11 上,为增强应用功能而可以执行的最常见的 11 种操作

Windows 11 中的几何图形

6. 源码

我做了个小 Demo 用户看看这篇文章提到的不同边框和 DWM_WINDOW_CORNER_PREFERENCE 设定下的效果,源码可以从这里获取:

[WPF] 在 Windows 11 中处理 WindowChrome 的圆角的更多相关文章

  1. 如何在windows 11中安装WSLG(WSL2)

    什么是 WSL WSL(Windows Subsystem for Linux):Windows 系统中的一个子系统,在这个子系统上可以运行 Linux 操作系统. 可以让开发人员直接在 Window ...

  2. 乘风破浪,遇见下一代操作系统Windows 11,迄今为止最美版本,原生支持安卓应用

    遇见下一代操作系统Windows 11 全新Windows体验,让您与热爱的人和事物离得更近. Windows一直是世界创新的舞台.它是全球企业的基石,助力众多蓬勃发展的初创公司变得家喻户晓.网络在W ...

  3. 在Windows 8.1及IE 11中如何使用HttpWatch

    提示:HttpWatch现已更新至v9.1.8,HttpWatch v9.1及以上的版本现都已支持Windows 7,8,8.1和IE 11. 如果你的HttpWatch专业版授权秘钥允许进入vers ...

  4. WPF中使用WindowChrome美化窗口过程中的一个小问题

    WPF中使用WindowChrome美化窗口,在园子里有几篇不错的文章,我也是参考练习过程中发现的问题,并记录下来. 在看过几篇教程后,给出的窗口很多出现这样一个问题,如果设置了窗口标题栏的高度大于默 ...

  5. WPF老矣,尚能饭否——且说说WPF今生未来(中):策略

    本文接上文<WPF老矣,尚能饭否——且说说WPF今生未来(上):担心>继续. “上篇”中部分精彩的点评: 虽然WPF不再更新了,但是基于WPF的技术还是在发展着,就比如现在的WinRT,只 ...

  6. UEFI+GPT模式下的Windows系统中分区结构和默认分区大小及硬盘整数分区研究

    内容摘要:本文主要讨论和分析在UEFI+GPT模式下的Windows系统(主要是最新的Win10X64)中默认的分区结构和默认的分区大小,硬盘整数分区.4K对齐.起始扇区.恢复分区.ESP分区.MSR ...

  7. WPF、Windows Forms和Silverlight间的联系和区别(转)

    WPF.Windows Forms和Silverlight间的联系和区别http://blog.csdn.net/bitfan/article/details/6128391 .NET Windows ...

  8. mysql绿色版在windows系统中的启动

    mysql绿色版在windows系统中的启动 1.下载mysql免安装版 例如:mysql-5.7.11-winx64 2.修改配置文件,my-default.ini名称改为:my.ini,文件里面的 ...

  9. 使用 Puppet 在 Windows Azure 中配备 Linux 和 Windows 环境

     发布于 2013-12-11 作者 Ross Gardler 微软开放技术有限公司 (MS Open Tech) 很高兴地宣布发行新的 Windows Azure Puppet 模块.通过这个模 ...

随机推荐

  1. 【第十八篇】- Maven Eclipse之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven Eclipse Eclipse 提供了一个很好的插件 m2eclipse ,该插件能将 Maven 和 Eclipse 集成在一起. 在最新的 Eclipse 中自带了 Maven,我们打 ...

  2. 借助AWR报告分析解决oracleCPU过高的问题

    原文地址:http://www.cnblogs.com/crystal-guoguo/p/4213458.html 简介:在oracle数据库中,有两个非常实用的自带监控工具EM(Enterprise ...

  3. SQLSERVER存储过程基础

    SQLSERVER存储过程基础 1.声明变量 DECLARE     @F001  SMALLINT,  (三元素,声明declare+变量名+类型) @F002  INTEGER, @F003  V ...

  4. 手机UI自动化之显示点触位置(触摸轨迹)

    上期回顾:Airtest源码分析--Android屏幕截图方式 不管是用Appium还是Airtest,或是其他手机UI自动化工具,你是不是经常遇到这种情况,代码明明执行了click或swipe,怎么 ...

  5. 重学VUE——vue 常用指令有哪些?

    一.什么是指令? 在 vue 中,指令以 v- 开头,是一种特殊的自定义行间属性.指令属性的预期值是一个表达式,指令的职责就是:表达式的值改变时,相应地将某些行为应用到DOM上.只有v-for是一个类 ...

  6. 优雅地创建未定义类PHP对象

    在PHP中,如果没有事先准备好类,需要创建一个未定义类的对象,我们可以采用下面三种方式: new stdClass() new class{} (object)[] 首先是stdClass,这个类是一 ...

  7. php 日期相关的类 DateInterval DateTimeZone DatePeriod

    * DateInterval <?php /** * Created by PhpStorm. * User: Mch * Date: 7/18/18 * Time: 21:30 */ $dat ...

  8. fliebeat配置手册

    1.  关于Filebeat 当你要面对成百上千.甚至成千上万的服务器.虚拟机和容器生成的日志时,请告别 SSH 吧!Filebeat 将为你提供一种轻量型方法,用于转发和汇总日志与文件,让简单的事情 ...

  9. P5445-[APIO2019]路灯【set,树状数组套线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P5445 题目大意 \(n+1\)个点,\(i\)和\(i+1\)个点之间有一条边,\(q\)个操作 断开/连接第\ ...

  10. CF1511G-Chips on a Board【倍增】

    正题 题目链接:https://www.luogu.com.cn/problem/CF1511G 题目大意 给出\(n*m\)的棋盘上每一行有一个棋子,双方轮流操作可以把一个棋子向左移动若干步(不能不 ...