春风十里不如你,全新Windows UI 3(WinUI 3) 的第一个实现Project Reunion 0.5

什么是WinUI

Windows UI库 (WinUI) 是适用于 Windows 桌面应用程序和 UWP 应用程序的本机用户体验 (UX) 框架。

WinUI is a user interface layer that contains modern controls and styles for building Windows apps. As the native UI layer in Windows it embodies Fluent Design, giving each Windows app the polished feel that customers expect.

‎WinUI是一个用户界面层,包含用于构建Windows应用的现代控件和样式。‎‎作为Windows中的原生UI层,它体现了‎‎流畅的设计‎‎,为每个Windows应用提供了客户所期望的抛光感觉。‎

通俗一点理解,WinUIUWP的UI层从Windows SDK的其它部分分离,并将从Windows转移到Nuget。现在建一个C++C#(.NET 5)程序,再从Nuget上装个WinUI 3的包套个UI层,一个基于Fluent Design,触摸友好,性能无与伦比的应用程序就诞生了。

什么是WinUI 3

Windows UI库(WinUI)3是用于构建新式Windows应用的原生用户体验(UX)平台。WinUI 3的此预览版既适用于桌面/Win32应用,也适用于UWP应用,并且包含VisualStudio项目模板和NuGet包,前者有助于你开始使用基于WinUI的用户界面构建应用,后者包含WinUI库。

从下图中,可以看出UI Framework技术的演进:

1992年的MFC -> 2002年的WinForms -> 2006年的WPF -> 2012年的UWP+Win UI2 Library,最终迎来了我们今天的主角WinUI 3(3rd generation of WinUI)

从“WinUI 2”到“WinUI 3”

WinUI 2.x可以在UWP应用程序中使用,并可通过XAML Islands纳入到新的或现有的桌面应用程序中。

Windows UI库(WinUI)3是用于构建新式Windows应用的原生用户体验(UX)框架。 它独立于Windows操作系统,作为Project Reunion的一部分提供。Project Reunion 0.5版本提供Visual Studio项目模板,可帮助你开始使用基于WinUI 3的用户界面构建应用。

WinUI 3 Project Reunion 0.5是WinUI 3的第一个稳定的支持版本,可用于创建可发布到Microsoft Store的生产应用。 此版本包含了稳定性更新和常规改进,使WinUI 3能够前向兼容,并可用于生产。

什么是Project Reunion

Project Reunion 是一组新的开发人员组件和工具,它们代表着 Windows 应用开发平台的下一步发展。 Project Reunion 提供了一组统一的 API 和工具,各种目标 Windows 10 OS 版本上的任何桌面应用都能够一致地使用它们。

Project Reunion 不会替代现有的桌面 Windows 应用平台和框架,例如 .NET(包括 Windows 窗体和 WPF)和 C++/Win32。 而是通过一组通用的 API 和工具(开发人员可以在这些平台中使用)来对这些现有平台进行补充。

在生产环境中,支持在 MSIX 打包桌面应用(C#/.NET 5 或 C++/Win32)中使用 Project Reunion 0.5。 可将使用 Project Reunion 0.5 的打包桌面应用发布到 Microsoft Store。 对于 UWP 应用,Project Reunion 0.5 仅作为预览版提供。 生产环境中使用的 UWP 应用不支持此版本。

Project Reunion 0.5 包含以下可在应用中使用的 API 和组件集

组件 说明
WindowsUI库3 WindowsUI库(WinUI)3是适用于Windows应用的下一代Windows用户体验(UX)平台。 此版本包含VisualStudio项目模板和NuGet包,前者有助于你开始使用基于WinUI的用户界面构建应用,后者包含WinUI库。
使用MRTCore管理资源 MRTCore提供API来加载和管理你的应用所使用的资源。 MRTCore是新式 Windows资源管理系统的简化版本。
使用DWriteCore呈现文本 通过DWriteCore,你可以获取用于呈现文本的所有当前DirectWrite功能,包括与设备无关的文本布局系统、硬件加速文本、多格式文本和广泛的语言支持。

面向Windows开发人员的Project Reunion优势

Project Reunion提供了各种Windows API,其实现与OS分离,并通过NuGet包发布给开发人员。Project Reunion并不打算替换Windows SDK。Windows SDK将继续按原样工作,并且Windows的许多核心组件将通过API不断改进,这些API通过OS和Windows SDK版本发布。建议开发人员按照自己的进度采用Project Reunion。

在不同的桌面应用平台中实现统一的API图面

想要创建桌面Windows应用的开发人员必须在多个应用平台和框架之间进行选择。尽管每个平台都提供了许多可供使用其他平台构建的应用使用的功能和API,但是某些功能和API仅供特定平台使用。Project Reunion统一了所有桌面Windows 10应用对Windows API的访问。无论选择哪种应用模型,你都可以访问ProjectReunion中提供的同一组Windows API。
随着时间的推移,我们计划对Project Reunion进行进一步的投资,以减少不同应用模型之间的差异。Project Reunion将同时提供WinRT API和本机CAPI。

在多个Windows 10版本中实现一致的支持

随着Windows API随新OS版本的发展而不断发展,开发人员必须使用版本自适应代码等技术来解决版本中的所有差异,以吸引其应用程序受众。这可能会增加代码和开发体验的复杂性。

Project Reunion API适用于Windows 10版本1809以及Windows 10的所有更高版本。这意味着,只要你的客户使用的是Windows 10版本1809或任何更高版本,就可以在新的Project Reunion API和功能发布后立即使用,而无需编写版本自适应代码。

加快发布节奏

新的Windows API和功能通常与每年以一次或两次的节奏发布的OS版本相关。Project Reunion将以更快的节奏发布更新,使你能够在创建Windows开发平台后更早、更快地访问这些创新。

ASTA到STA线程模型

如果要将代码从现有UWP应用迁移到使用Project Reunion的新C#/.NET5或C++/Win32/WinUI3项目,请注意,新项目使用单线程单元(STA)线程模型,而不是UWP应用使用的应用程序STA(ASTA)线程模型。如果代码采用ASTA线程模型的非可重入行为,则代码可能不会按预期方式运行。

WinUI 3路线图

控件和特性

  • * Coming to a future version of WinUI 3.
  • ** Work in progress.
兼容性/特性 WinUI 3 UWP XAML & WinUI 2 WPF WinForms MFC
Windows app types supported UWP (Preview) and Win32 UWP Win32 Win32 Win32
Windows versions supported Windows 10 (1809+) Windows 10 (1703+) Windows XP or higher Windows XP or higher Windows XP or higher
Supported on all Windows device families √*
Native C/C++
.NET 5 Support
WebView2 (Chromium-based engine) √** √**
Built-in Fluent Design controls
Built-in support for modern input (e.g. touch, pen, gamepad*)
Uses latest DirectX version for graphics performance
High performance data binding (x:Bind)
Input Validation

WinUI 3控件库

查看WinUI 3控件库(以前称为 XAML控件库 - WinUI 3版本)以获取示例应用,该示例应用包含属于WinUI 3 Project Reunion 0.5的所有控件和功能。

git clone --single-branch --branch winui3 https://github.com/microsoft/Xaml-Controls-Gallery.git
git checkout winui3

Visual Studio支持

VS 版本 WinUI 3 - Project Reunion 0.5
16.8
16.9 是,但没有热重载、实时可视化树或实时属性资源管理器功能
16.10 预览版 是,具有所有 WinUI 3 工具

开发环境要求

1. 确保开发计算机上已安装Windows 10版本1809(内部版本17763)或更高版本的OS。

2. 如果尚未安装Visual Studio 2019版本16.10预览版(或更高版本),请先安装。

1)安装Visual Studio时,必须包含以下组件:

  • 在安装对话框的“工作负载”选项卡上,确保选择了“通用 Windows 平台开发”。
  • 在安装对话框的“单个组件”选项卡上,确保在“SDK、库和框架”部分选择了Windows 10 SDK(10.0.19041.0)。

2)要构建.NET应用,还必须包含以下组件:

  • 在安装对话框的“工作负载”选项卡上,确保选择了“.NET桌面开发”。

3)要构建C++应用,还必须包含以下组件:

  • 在安装对话框的“工作负载”选项卡上,确保选择了“C++桌面开发”。
  • 在安装对话框右侧的“安装详细信息”窗格中,确保在“通用Windows平台开发”部分选择了“C++(v142)通用Windows平台工具”可选组件。

3. 如果以前安装了VisualStudio的WinUI3预览版扩展,请卸载该扩展。

4. 请确保系统中已为正式NuGet服务索引启用了NuGet包源https://api.nuget.org/v3/index.json

a. 在VisualStudio中,选择"工具""->NuGet包管理器->包管理器设置"以打开"选项"对话框。

b. 在"选项"对话框的左窗格中,选择"包源"选项卡,并确保将指向的nuget.org的包源https://api.nuget.org/v3/index.json作为源URL。

5. 下载并安装适用于VisualStudio的项目Project Reunion 0.5扩展。扩展有两个版本:一个用于桌面(c#/.NET5或c++/WinRT)应用,另一个用于UWP应用。

Project Reunion 0.5 发行版有两个可用的 Visual Studio 扩展:Project Reunion VSIX 和 Project Reunion 预览 VSIX 。 Project Reunion VSIX 包含可用于生成 MSIX 打包桌面生产应用的项目模板。 Project Reunion 预览 VSIX 包含可用于生成 MSIX 打包桌面应用或 UWP 应用的实验性项目模板。

若要在desktop中使用Project Reunion(c#/.NET5或c++/WinRT)应用:

  • 在VisualStudio2019中,单击“扩展”>“管理扩展”,搜索Project Reunion,然后安装Project Reunion扩展。
  • 或者,可以直接从Visual Studio Marketplace下载并安装项目Project Reunion 0.5扩展

若要在UWP应用中使用Project Reunion,你必须安装不支持在生产环境中使用的扩展预览版本:

  • 卸载项目的任何现有版本。
  • 在VisualStudio2019中,单击"扩展"">管理扩展",然后单击左下角的"更改扩展设置"。安装旧版本之前,请关闭为所有用户安装的包的自动更新。
  • 下载并安装项目Project Reunion 0.5预览扩展。

安装完成之后,我们新建项目就能看到关于WinUI 3的新项目模板了。

6. 若要在Visual Studio 2019 16.10 Preview中使用WinUI 3工具(如"实时可视化树"、"热重载"和"实时属性资源管理器"),必须使用Visual Studio预览功能启用WinUI 3工具。

  1. Navigate to the Preview Features page by going to Tools -> Options -> Environment -> Preview Features
  2. Click on "Enable UI Debugging Tooling for WinUI 3 Projects"
  3. Click on OK

7. 若要接收来自最新稳定版本的项目Project Reunion 0.5的所有修补程序,需要将.NET SDK显式设置为最新版本。为此,请将以下项组添加到.csproj文件中,并保存项目。

<ItemGroup>            
    <FrameworkReference Update="Microsoft.Windows.SDK.NET.Ref" RuntimeFrameworkVersion="10.0.18362.16" />
    <FrameworkReference Update="Microsoft.Windows.SDK.NET.Ref" TargetingPackVersion="10.0.18362.16" />
</ItemGroup>

8. 如果你在使用扩展应用Reshaper,建议最好更新到最新版为好

创建使用Project Reunion的新项目

适用于Visual Studio 2019(包含适用于"桌面应用"和"UWP应用的预览扩展"的扩展的项目"0.5扩展")提供使用基于WinUI 3的UI层生成项目的项目模板,并提供对所有其他项目的所有其他Api的访问权限。

支持在生产环境中使用的桌面 (c #/.NET 5 和 c + +/WinRT) 项目模板。 UWP 项目模板仅作为开发人员预览版提供,不能用于生成适用于生产环境的应用。

创建项目后,除了桌面和 UWP 应用常用的所有其他 Windows 和 .NET API 之外,你还可以使用以下 Project Reunion API 和组件

创建适用于C#和.NET 5的WinUI 3桌面应用

1. 打开Visual Studio 2019 Preview 16.10,选择创建新项目

2. 选择一个基于WinUI 3桌面的空白模板。

3. 输入项目名字demoDesktopInWinUi3,点击创建按钮。

4. 在下面的对话框中,将“目标版本”设置为Windows 10 版本 2004(内部版本 19041),并将“最低版本”设置为Windows 10 版本 1809(内部版本 17763),然后单击“确定” 。

因为WinUI框架最低要求1809版本的Windows10。

5. 接下来,很快会创建好解决方案和两个对应的项目。其中,

  • 项目名称(桌面):此项目包含应用的代码。App.xaml文件和App.xaml.cs和代码隐藏文件定义了一个Application类,它表示你的应用实例。MainWindow.xaml文件和MainWindow.xaml.cs代码隐藏文件定义了一个MainWindow类,它表示你的应用显示的主窗口。这些类派生自WinUI提供的Microsoft.UI.Xaml命名空间中的类型。

  • 项目名称(程序包):这是一个Windows 应用程序打包项目,已配置该项目以将应用生成到MSIX包中。 这提供了一种新式部署体验、通过包扩展与Windows 10功能集成的功能以及更多其他功能。 此项目包含应用的程序包清单,默认情况下它是你的解决方案的启动项目

6. 若要向应用项目中添加新项,请在解决方案资源管理器中右键单击“项目名称(桌面)”项目节点,然后选择“添加” -> “新项”。 在“添加新项”对话框中,选择“WinUI”选项卡,选择要添加的项,然后单击“添加”。

7. 生成并运行解决方案,确认应用运行时不会出错。

第一次编译,就遇到一个报错,This version of Project Reunion requires WinRT.Runtime.dll version 1.2 or greater,差点慌了。

根据微软给的提示,就两条路,要么升级.Net SDK到v5.0.6版本,我查了下我自己的,才v5.0.3,我还以为真的有新版本,结果到下载页一看,傻眼了,最新版不也就才到v5.0.5,哪来的v5.0.6,差点走偏。

后来,突然反应过来,这个关于Microsoft.Windows.SDK.NET.Ref FrameworkReference的提示很眼熟,哦,原来就是前面提到的开发环境中第7点,果然就是它,那肯定就靠你了,大兄弟。

用Visual Studio Code打开当前目录,找到“项目名称(桌面)”项目的.csproj,在ItemGroup节点中,插入:

    <FrameworkReference Update="Microsoft.Windows.SDK.NET.Ref" RuntimeFrameworkVersion="10.0.18362.16" />
    <FrameworkReference Update="Microsoft.Windows.SDK.NET.Ref" TargetingPackVersion="10.0.18362.16" />

保存后,回到项目一看,重新生成所有,完事,就这么好了。

8. 废话少说,Ctrl+F5,运行吧。

构建基本的WinUI 3桌面应用

应用程序解决方案

默认情况下,该解决方案包含两个项目:应用程序本身以及用于创建.msix应用包的另一个项目。

当前需要MSIX应用包才能将使用Project Reunion 0.5的应用部署到其他计算机。但是,未来版本的Project Reunion将支持部署未打包应用。

应用程序项目

双击应用程序项目文件(或右键单击并选择“编辑项目文件”),这样便会在XML文本编辑器中打开该文件。

我们可以看到TargetFramework是指定为net5.0-windows10.0.19041了,今后这是.NET的主要实现。

还有,ItemGroup节点下,各种Project Reunion功能的NuGet PackageReference元素,包括WinUI

MainWindow.xaml文件

XAML Window类已扩展为支持桌面窗口,从而转换为UWP和桌面应用模型所使用的每个低级别窗口实现的抽象。 具体而言,UWP使用CoreWindow,而Win32使用窗口句柄(或称HWND)和相应的Win32 API

从托管的C#/.NET 5应用调用原生函数

在解决方案上右键,选择管理解决方案的Nuget包,搜索PInvoke.User32,将PInvoke.User32安装到项目名称(桌面)中。

前往App.xaml.cs中,定义MainWindowWindowHandle接收当前程序的句柄,在OnLaunched函数中获取当前程序句柄。

若要获取窗口句柄,请使用GetActiveWindow方法。 此方法返回当前活动窗口的窗口句柄(在激活目标窗口之后调用此方法)。

/// <summary>
/// Invoked when the application is launched normally by the end user.  Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    m_window = new MainWindow();
    m_window.Activate();

    m_windowhandle = PInvoke.User32.GetActiveWindow();
}

private Window m_window;

IntPtr m_windowhandle;
public IntPtr MainWindowWindowHandle { get { return m_windowhandle; } }

然后前往MainWindow.xaml.cs中,找到myButton_Click事件,追加逻辑,通过调用原生函数来实现当前窗体的最大化动作。

private void myButton_Click(object sender, RoutedEventArgs e)
{
    myButton.Content = "Clicked";

    IntPtr hwnd = (App.Current as App).MainWindowWindowHandle;
    PInvoke.User32.ShowWindow(hwnd, PInvoke.User32.WindowShowStyle.SW_MAXIMIZE);
}

编译并运行应用,按“单击我”按钮,应用窗口应最大化。

以“完全信任权限”模式运行桌面应用

WinUI 3提供了一种功能,使应用程序能够在AppContainer的安全沙盒以外以“完全信任权限”运行。

在UWP应用的时候,我们总是会默认以受限制的方式运行,而基于WinUI 3的不会,接下来的举个例子:

MainWindow.xaml文件的内容改为:

<StackPanel 
    Orientation="Horizontal" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Center">
    <Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
    <ContentDialog x:Name="contentDialog" CloseButtonText="Close">
        <StackPanel>
            <TextBlock Name="cdTextBlock"/>
        </StackPanel>
    </ContentDialog>
</StackPanel>

然后前往MainWindow.xaml.cs中,找到myButton_Click事件,追加逻辑,从System.Diagnostics调用.NET API以获取当前进程中加载的模块,循环访问Process.Modules对象中的每个ProcessModule

private async void MyButton_Click(object sender, RoutedEventArgs e)
{
    myButton.Content = "Clicked";

    var description = new System.Text.StringBuilder();
    var process = System.Diagnostics.Process.GetCurrentProcess();
    foreach (System.Diagnostics.ProcessModule module in process.Modules)
    {
        description.AppendLine(module.FileName);
    }

    cdTextBlock.Text = description.ToString();
    await contentDialog.ShowAsync();
}

编译并运行应用,按“单击我”按钮,对话框应显示进程列表。

参考

posted @ 2021-04-18 14:49  TaylorShi  阅读(16762)  评论(2编辑  收藏  举报