WinUI 3 试玩报告

1. 什么是 WinUI 3#

在微软 Build 2020 开发者大会上,WinUI 团队宣布可公开预览的 WinUI 3 Preview 1,它让开发人员可以在 Win32 中使用 WinUI。WinUI 3 Preview 1 包含新的 VisualStudio 项目模板,可以创建面向 .NET 5 的 C# 和 C++/Win32 项目。从技术上讲,WinUI 3 将 UWP 的 XAML、Composition 和 Input 层分离,并通过NuGet将它们独立分发给针对Windows 10 版本 1803 及更高版本的 Win32 应用。

WinUI 3 适用于 Win32 和 UWP,这篇文章主要讨论 Win32 的情况。

2. 理解 WinUI 3#

以前我们总是抱怨 WPF 多年都不提供新的主题,不提供新的控件,性能又没提升。现在微软索性把什么都是新的 WinUI 3 提供给桌面开发,没 WPF 什么事了。

简单来说,UWP 的开发体验不好(关于这个话题真是一言难尽),而且出了 Bug 还必须等待下半年的 Windows 更新进行修复,但微软的开发人员专心给 UWP 的 UI 层加各种功能;.NET Core 更新很快,但很少人有兴趣有动力给陈旧的 WPF 的 UI 层进行大幅度的改进。于是 WinUI 将 UWP 的 UI 层从 Windows SDK 的其它部分分离,并将从 Windows 转移到 Nuget。现在建一个 C++ 或 C#(.NET 5) 程序,再从 Nuget 上装个 WinUI 3 的包套个 UI 层,一个基于 Fluent Design,触摸友好,性能无与伦比的应用程序就诞生了。

上图列举了 WinUI 3 和其他平台对比的部分特性,除此之外 WinUI 3 还有很多好处,例如开源、更新更快、更新不与系统版本绑定等,更详细的内容还是看微软自己怎么宣传吧:

WinUI - The modern native UI platform of Windows.

不过要用上 WinUI 3 还要等一年半载。下面是微软给出的发布路线图,目前我们也只能用 Preview 版尝尝鲜。

3. 试玩WinUI 3#

要试玩 WinUI 3 首先要有 Windows 10 1803 以上版本的电脑(WinUI 3 最低支持1803),然后还需要使用 Visual Studio 2019 16.7 以上版本(目前只能安装预览版)。安装 Visual Studio 时要把以下工作负载全都选上:

  • .NET 桌面开发

  • 通用 Windows 平台开发

  • 使用 C++ 的桌面开发

  • 适用于通用 Windows 平台负载的 C++(V142) 通用 Windows 平台工具可选组件

当然 .NET 5.0 也要装上。

然后在 https://aka.ms/winui3/previewdownload 下载并安装 WinUI 3 Project Templates 扩展,这样才可以在  Visual Studio 创建 WinUI 的项目。

可选  C++ 或 C# ,这里我选择了 C# 的“Blank App, Packaged
(WinUI in Desktop)”项目,并选择了对应的 Windows 平台:

项目创建后 Visual Studio 生成了两个项目。第一个包含应用的代码,代码结构基本和 UWP 一样,只是少了用于打包应用的 Package.appxmanifest 和一些图片。从依赖项里可以看到项目已经安装了 Microsoft.WinUI 3 的包。从项目属性里可以看到这就是个 .NET 5 的项目。

Visual Studio 生成的第二个项目是一个 Windows 应用程序打包项目,该项目经配置后可将应用生成为适合部署的 MSIX 程序包。 也就是说 UWP 项目中用于打包的部分被独立出来了。这个项目还应该是解决方案的启动项目。运行这个项目后创建的应用会添加到开始菜单中,这点也和UWP一样。

到这里为止都和预期的一样,我之后还尝试了将 UWP 应用移植到 WinUI ,基本上只需要将 Windows.UI 命名空间改为 Microsoft.UI就可以了,XAML 和 C# 代码完全不用变。只可惜目前 WinUI 还很简陋,Win2D、Community Toolkit 等微软自己发布的 UWP 包都还没有 WinUI 版本。而且没有设计视图,XAML 视图也没有智能感知,现在想要用 WinUI做些什么有趣的项目会很困难。不过从目前的移植难度上来看,将来正式发布后应该可以完整地将 UWP 的 UI 的开发经验运用在 WinUI 上。

4. 和 WPF 及 UWP 进行对比#

既然 WinUI 3 开发模式和 WPF 及 UWP 都很像,我当然对它们之间的对比很感兴趣。

命名#

首先说说命名,“WinUI” 光这个名字就 Win 了。 “UWP” 太高雅,我敢打赌国内有些 UWP 的开发(例如我)都不能好好地把 UWP 的全称拼出来;“WPF” 好些,但 WPF 的含义也让人很疑惑。而 Windows UI 简称 WinUI ,意义和发音都很清晰明确。不过这三个都比很多人都不会读的 “Xamarin” 强多了。

可是有了 WinUI 3 ,就会有人问“那 WinUI 2 呢?”WinUI 2是一个 UWP 的控件库,当然的只能用在 UWP 上。这就很尴尬了,WinUI 的 3 和 2 根本不是同一个概念,实在很容易让人混淆,说不定以后会把后缀的 3 去掉(我这篇文章就常常懒得理写这个3)。而且 UWP 中代码的命名空间以 Windows.UI 开头,在 WinUI 3 中则 Microsoft.UI ,按着 Office 365 改名为 Microsoft 365、Bind Ads 改名为 Microsoft Advertising 这些经验,该不会以后 WinUI 可能改名为 Microsoft UI ,简称 MiUI 吧?

权限#

权限方面是 WinUI 的一个亮点,因为它本质上就是个 Win32 程序,可以放开手脚随便来。相对的 UWP 有很严格的权限限制,开发 UWP 时常常会感到绑手绑脚。例如下面这段代码,大部分 WPF 开发者都难以想象只是最小化 UWP 程序而已,它就不能好好运行了:

Copyint count = 0;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += (s, e) =>{myButton.Content = count++;};
timer.Start();

UWP 的生命周期如上图,当 UWP 处于 background 运行或 suspended 状态时应用基本处于暂停状态,也也不会处理UI功能。我明白这是 UWP 为了省电、安全等原因才这样设计,但对开发人员来说真的太不方便。而 WinUI 应用基本上就是个 Win32 应用,目前看来不会有这些坑。

开发体验#

说起开发体验,WPF 好歹还算正常,Visual Studio 的设计视图运行正常,编译起来也快。UWP 编译很慢,设计视图经常出问题,Blend 也时好时坏把设计师都气跑了。就算完全按着官方的文档完成一个 UWP App,甚至一行代码都不改,发布到商店后还是有可能崩溃。而对于应用商店,真是千言万语汇聚成一个草花头。

现在 WinUI 的 XAML 视图连智能感知都没有,也没有设计视图,实在没法谈开发体验。很难猜测正式发布的时候会怎么样,希望至少和WPF保持一致吧。

性能#

WPF 总是给人“慢”的印象,除了因为在它刚出来的时候(10年前)电脑性能不够导致留下了刻板印象,还有一个主要原因是:它真的很慢。

UWP 的 XAML 有很优秀的性能表现,除此之外为了照顾已经不存在的 Windows Phone 的贫弱性能,很多控件模版都经过精心设计并大幅简化。

为了验证 WinUI 的性能我写了下面这些代码,然后分别移植到 WPF .Net Framework 4.8、WPF .NET 5、UWP、WinUI(WPF 和 UWP/WinUI 的代码稍微有一点不同):

Copyfor (int i = 0; i < 50; i++)
{var rectangle = new Rectangle{Height = 500,Width = 500,Opacity = ((double)i + 40) / 100d,RadiusX = 108,RadiusY = 98,StrokeThickness = 3,Stroke = new SolidColorBrush(Color.FromArgb(255, 75, 75, (byte)(i * 250d / 50d))),RenderTransformOrigin = new Point(0.5, 0.5)};Root.Children.Add(rectangle);var angle = i * 360d / 50d;var transform = new RotateTransform{Angle = angle};rectangle.RenderTransform = transform;var storyboard = new Storyboard();storyboard.Children.Add(new DoubleAnimation { Duration = TimeSpan.FromSeconds(1), From = angle, To = angle + 360 });Storyboard.SetTarget(storyboard, transform);Storyboard.SetTargetProperty(storyboard, "Angle");storyboard.RepeatBehavior = RepeatBehavior.Forever;storyboard.Begin();
}

上面这段代码是让50个矩形旋转,十分考验 WPF 的性能。结果可以说出乎意料。


CPU内存GPU
WPF .NET Framework 4.8126076
WPF .NET 5.0128572
UWP32836
WinUI56595

我的环境是 i7-6820HQ 及集成显卡。WPF 平台占用 70 多%的 GPU,这我大致能猜到。UWP 十分流畅,GPU 只占用 WPF 的一半,CPU 和 内存都有出色表现,不过我还以为会更低的。

WinUI 这个浓眉大眼的我真的万万没想到,不仅掉帧明显,还占用了几乎 100% GPU,也就是说它连这么简单的代码都跑不起来。()顺便一提,将测试代码中旋转的矩形减少为10个,WPF 的程序占用 32% GPU,而 WinUI 占用 70 多%。)

从上面的数据基本可以说明,WinUI 离设计目标还十分遥远,毕竟是预览版,还有一年半载可以慢慢优化。

5. 结语#

总的来说微软雄心勃勃,可是现在拿出来的 WinUI 预览版还差得太远,功能未完善,性能不及预期。我觉得大致方向没错,WinUI 对 C++、WPF、UWP 开发者都是个新的工具新的机遇,可以关注一下。

6. Q & A#

Windows 7 怎么办?#

按微软公布的路线图,再包括跳票等因素,等 WinUI 真正可用时 Windows 7 已停止更新很久,到时 Windows 7 的占有率可能已经下降到开发者不会关心的程度。

基于 .NET Core 的 Wpf 还是 WinUI?#

假使不想花精力将现有项目迁移到 WinUI,或者对来自 UWP 的 WinUI 没信心,又或者舍不得 Windows 7 的用户,并且对触摸没需求,当然可以继续选用 WPF,基于 .NET Core 的 WPF 会是个很好的选择。

MAUI 还是 WinUI ?#

MAUI 还在很遥远的将来(2021年11月),我没试玩过,所以不好评价。如果有跨平台需求当然只能选 MAUI,如果 WinUI 团队技高一筹实现了 MAUI 难以企及的超高性能,那就选 WinUI。不过 MAUI 这个名字太过普通/普遍,可能会被逼着改名吧。

那 UWP 呢?#

权限受限的 UWP 可以说是人畜无害,对用户来说可能也是个不错的选择。而且 UWP 还支持 Xbox 和 Hololens 等平台,目前看来还是有它的市场。

Winforms 呢?

人只有忘却了过去,才能好好活着。

WinUI 有未来吗?

我做了好多年 Silverlight 开发,买了5、6部 Windows Phone 手机,写了几十篇 UWP 文章,根据我丰富的经验,我可以肯定 WinUI 是有未来的。

8. 参考

WinUI - The modern native UI platform of Windows.

Introducing WinUI 3 Preview 1 - Windows Developer Blog

Get started with WinUI 3 for desktop apps Microsoft Docs

GitHub - microsoft_microsoft-ui-xaml

Windows UI Library Roadmap

WinUI 3.0_ The future of Windows controls

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[JS-BOM]BOM_Window窗口对象

Window&#xff1a;窗口对象 1. 创建2. 方法1. 与弹出框有关的方法&#xff1a;alert() 显示带有一段消息和一个确认按钮的警告框。confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框。* 如果用户点击确定按钮&#xff0c;则方法返回true* 如果用户点击取消按钮&#…

记一次EF Core连接MySql、Oracle

点击上方“Dotnet9”添加关注哦上上个月写的一篇文章&#xff0c;今天有同事问我使用EF Core连接MySql和Oracel的问题&#xff0c;我把这篇文章直接甩给了他。下面是正文&#xff1a;这几天研究了EF Core对MySql、Oracle的操作&#xff0c;包括连接、简单查询等&#xff0c;操作…

[JS-BOM]BOM_Location地址栏对象

Location&#xff1a;地址栏对象 1. 创建(获取)&#xff1a;1. window.location2. location2. 方法&#xff1a;* reload() 重新加载当前文档。刷新3. 属性* href 设置或返回完整的 URL。示例代码如下: <!DOCTYPE html> <html lang"en"> <head>&l…

基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)

系列文章使用 abp cli 搭建项目给项目瘦身&#xff0c;让它跑起来完善与美化&#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API&#xff0c;包装返回模型再说Swagger&#xff0c;分组、描述、小绿锁接入GitHub&#xff0c;用JWT保护你的API异常处理和…

Codeforces Round #719 (Div. 3)/ Codeforces Round #720 (Div. 2)

A. Do Not Be Distracted! 题意&#xff1a; 一件事情一但开始&#xff0c;只能做完才能做别的事&#xff0c;当出现一件事不连续出现时&#xff0c;教师会怀疑 题目&#xff1a; Polycarp has 26 tasks. Each task is designated by a capital letter of the Latin alphab…

[JS-BOM]BOM_History历史记录对象

History&#xff1a;历史记录对象 1. 创建(获取)&#xff1a;1. window.history2. history2. 方法&#xff1a;* back() 加载 history 列表中的前一个 URL。* forward() 加载 history 列表中的下一个 URL。* go(参数) 加载 history 列表中的某个具体页面。* 参数&#xff1a;* …

dotNET Core 3.X 使用 Autofac 来增强依赖注入

在上一篇《dotNET Core 3.X 依赖注入》中简单介绍了 dotNET Core 框架本身的依赖注入功能&#xff0c;大部分情况下使用框架的依赖注入功能就可以满足了&#xff0c;在一些特殊场景下&#xff0c;我们就需要引入第三方的注入框架。为什么要使用 Autofac&#xff1f;如果您在之前…

[JS-DOM]DOM概述

DOM&#xff1a; * 概念&#xff1a; Document Object Model 文档对象模型* 将标记语言文档的各个组成部分&#xff0c;封装为对象。可以使用这些对象&#xff0c;对标记语言文档进行CRUD的动态操作* W3C DOM 标准被分为 3 个不同的部分&#xff1a;* 核心 DOM - 针对任何结构…

基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)

系列文章使用 abp cli 搭建项目给项目瘦身&#xff0c;让它跑起来完善与美化&#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API&#xff0c;包装返回模型再说Swagger&#xff0c;分组、描述、小绿锁接入GitHub&#xff0c;用JWT保护你的API异常处理和…

2021年度训练联盟热身训练赛第一场 H题On Average They‘re Purple(BFS)

题意&#xff1a; 给你一些联通关系&#xff0c;问Bob先选择一些路径&#xff08;1~n&#xff09;联通&#xff0c;Alice在路径上染色&#xff0c;Bob的目的是选择一些路径使得染色变化最小&#xff0c;对于Alice来说&#xff0c;需要使得在Bob选择的&#xff08;1−n1-n1−n&…

[JS-DOM]核心DOM模型(Document,Element,Node)

核心DOM模型&#xff1a; * Document&#xff1a;文档对象1. 创建(获取)&#xff1a;在html dom模型中可以使用window对象来获取1. window.document2. document2. 方法&#xff1a;1. 获取Element对象&#xff1a;1. getElementById() &#xff1a; 根据id属性值获取元素对象。…

使用请求头认证来测试需要授权的 API 接口

使用请求头认证来测试需要授权的 API 接口Intro有一些需要认证授权的接口在写测试用例的时候一般会先获取一个 token&#xff0c;然后再去调用接口&#xff0c;其实这样做的话很不灵活&#xff0c;一方面是存在着一定的安全性问题&#xff0c;获取 token 可能会有一些用户名密码…

双端队列 BFS + Chamber of Secrets CodeForces - 173B

题意&#xff1a; 一个 nmn\times mnm 的图&#xff0c;现在有一束激光从左上角往右边射出&#xff0c;每遇到 ‘#’&#xff0c;你可以选择光线往四个方向射出&#xff0c;或者什么都不做&#xff0c;问最少需要多少个 ‘#’ 往四个方向射出才能使光线在第 n 行往右边射出。 …

[JavaWeb-Bootstrap]Bootstrap概述

Bootstrap&#xff1a; 1. 概念&#xff1a; 一个前端开发的框架&#xff0c;Bootstrap&#xff0c;来自 Twitter&#xff0c;是目前很受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JavaScript 的&#xff0c;它简洁灵活&#xff0c;使得 Web 开发更加快捷。* 框架:一个半成…

程序员过关斩将--作为一个架构师,我是不是应该有很多职责?

点击上方“蓝字”关注我们领取架构书籍每一个程序员都有一个架构梦。上面其实本质上是一句富有事实哲理的废话&#xff0c;要不然也不会有这么多人关注你的公众号。这些年随着“企业数字化”转型的口号&#xff0c;一大批企业奔跑在转型的路上&#xff0c;希望领先一步对手将企…

Excel使用技巧,补充中。。。

Excel表怎么把名字按字母排序 然后后面的数据也跟着变动 1、首先在excel表格的A列单元格中输入字母&#xff0c;选中需要排序的A列和B列单元格。 2、然后点击工具栏“数据”中的“排序”。 3、在弹出的对话框中的“次序”下拉框中选择“自定义序列”。 4、然后在弹出的对话…

[JavaWeb-Bootstrap]Bootstrap快速入门

快速入门 1. 下载Bootstrap2. 在项目中将这三个文件夹复制3. 创建html页面&#xff0c;引入必要的资源文件<!DOCTYPE html><html lang"zh-CN"><head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" conten…

递归函数中局部变量和全局变量

有时候会因为不注意递归函数中局部变量和全局变量&#xff0c;而导致结果和我们期望的不一致&#xff0c;递归中&#xff0c;在递归中的局部变量和全局变量&#xff0c;可以类似的看成函数调用时传递方式的按值传递&#xff08;局部变量&#xff09;和引用传递&#xff08;全局…

基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)

系列文章使用 abp cli 搭建项目给项目瘦身&#xff0c;让它跑起来完善与美化&#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API&#xff0c;包装返回模型再说Swagger&#xff0c;分组、描述、小绿锁接入GitHub&#xff0c;用JWT保护你的API异常处理和…

[JavaWeb-Bootstrap]Bootstrap响应式布局

响应式布局 * 同一套页面可以兼容不同分辨率的设备。 * 实现&#xff1a;依赖于栅格系统&#xff1a;将一行平均分成12个格子&#xff0c;可以指定元素占几个格子 * 步骤&#xff1a;1. 定义容器。相当于之前的table、* 容器分类&#xff1a;1. container&#xff1a;两边留白…