专栏首页walterlv - 吕毅的博客使用 Microsoft.UI.Xaml 解决 UWP 控件和对老版本 Windows 10 的兼容性问题

使用 Microsoft.UI.Xaml 解决 UWP 控件和对老版本 Windows 10 的兼容性问题

使用 Microsoft.UI.Xaml 解决 UWP 控件和对老版本 Windows 10 的兼容性问题

发布于 2018-07-21 13:51 更新于 2018-07-24 01:17

虽然微软宣称 Windows 10 将是最后一个 Windows 版本,但由于年代跨越实在太久远,兼容性依然是避不开的问题。Microsoft.UI.Xaml 的预览版现已退出,旨在解决 UWP UI 控件在各个不同版本 Windows 上的兼容性问题。

本文将简单了解一下 Microsoft.UI.Xaml 库,然后实际看看它的效果。


Windows 10 的兼容性问题

在创建 UWP 应用的时候,我们可以选择目标版本和最低版本。目标版本决定了我们能使用的最新 API,最低版本决定了我们需要支持的最低版本的 Windows 10。

▲ 图中目标版本为 17134,最低版本为 14393。事实上,目标版本必须是 17134,最低只能支持到 14393。

然而,每一次新版本 Windows 10 的推出,都带来大量新的开发 API。可以去官方文档 Choose a UWP version - UWP app developer - Microsoft Docs 了解各个版本 Windows 10 新增的功能简介。

微软在 Windows 10 16299 版本带来了 XAML 条件编译,用以在 XAML 中兼容不同版本的 Windows 10,然而这意味着必须选择 16299 作为最低 API 版本才能正常使用此功能。当然,XAML 条件编译还是带来了不少方便的特性呢,阅读 win10 uwp xaml 兼容多个版本条件编译 - 林德熙 可以了解 XAML 条件编译的使用方法,顺便收获一只猫。

Windows 10 也在各个版本新增了一些控件。那么问题来了,要支持最低版本就不能使用新控件。Windows 10 又不像 iOS 那样更新率高,意味着根本不能使用新控件进行开发。

Microsoft.UI.Xaml 库

于是微软就推出了在 上推出了 NuGet 包 [Microsoft.UI.Xaml](https://www.nuget.org/packages/Microsoft.UI.Xaml)。

使用此包,你需要将 UWP 的 目标版本设为 17134,支持的 最低版本只能到 14393,不能更低。

官方对此包的描述为:

This package provides backward-compatible versions of Windows UI features including UWP XAML controls, and Fluent styles and materials. It is part of the Windows UI Library.

即提供各种 Windows UI 功能的向后兼容性,包括 UWP XAML 控件、Fluent 流畅设计样式和画刷。当然,不支持亚克力效果的系统版本虽然画刷能用,不崩溃,但也没有效果的。

Microsoft.UI.Xaml 的上手方法

安装 Microsoft.UI.Xaml 后,Visual Studio 会自动打开 readme.txt 文件提示我们用法:

Thanks for installing the WinUI nuget package! Don’t forget to add this to your app.xaml: <Application.Resources> <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/> </Application.Resources> See http://aka.ms/winui for more information.

即我们需要在 App.xaml 文件中添加 <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/> 作为应用程序的全局资源。不过,官方文档 Getting started with the Windows UI library 中有对此更详细的描述。

如果我们是新 UWP 程序,这样写是没问题的:

<Application>
    <Application.Resources>
        <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/> 
    </Application.Resources>
</Application>

但如果基于原有的程序进行兼容性改造,可能原 Application 中已经有资源了,就必须换一种写法:

<Application>
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <XamlControlsResources  xmlns="using:Microsoft.UI.Xaml.Controls"/>
            </ResourceDictionary.MergedDictionaries> 
        </ResourceDictionary>
    </Application.Resources>
</Application>

当然,以上这种改造在各种 XAML 上的行为都是一样的,比如我在 StackOverflow 上回答的问题 Use ResourceDictionary with other Styles in WPF 也是这样的改法,其中说明了必须这样修改的原因。

不过没有结束,在需要使用到新版本 Windows 10 控件的 XAML 文件中,需要添加命名空间前缀:

xmlns:controls="using:Microsoft.UI.Xaml.Controls"

这样才能在 XAML 中使用 Microsoft.UI.Xaml 库中的新控件:

<Grid>
    <controls:NavigationView x:Name="WalterlvDemoView">
        <controls:NavigationView.MenuItems>
            <ListViewItem Content="Home" />
            <ListViewItem Content="Demo" />
            <ListViewItem Content="About" />
            <ListViewItem Content="https://walterlv.github.io/" />
        </controls:NavigationView.MenuItems>
    </controls:NavigationView>
</Grid>

还记得本文开头那张 Visual Studio 的兼容性提示图片吗?使用了 Microsoft.UI.Xaml 库之后,不会再有提示了。这不是欺骗,是真的具备了对早期系统的兼容性。

于是,一些广泛使用的 UWP 应用终于不用各种自己写控件来兼容低版本的 Windows 10 了。

当然除了在 XAML 中,也可以在 C# 代码中使用库中的新 API。

解决意料之外的错误

一切可以那么顺利?不一定,你可能在刚刚把 <XamlControlsResources /> 加入之后,就会发现程序启动即崩溃了……

然后提示:

System.Runtime.InteropServices.COMException HResult=0x80004005 Message=Error HRESULT E_FAIL has been returned from a call to a COM component. Source= StackTrace:

不得不说,微软再一次把内部错误暴露了出去。实际的错误原因是 —— 目标 SDK 需要设置为 17134 —— 这是必须的!

当然,这个版本号并不是跟随系统的,而是跟随 Microsoft.UI.Xaml 库的。库如果更新有新系统的控件,那么你更新库之后就需要再次更新目标 SDK 版本了。

本文会经常更新,请阅读原文: https://walterlv.com/post/getting-started-with-microsoft-ui-xaml.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • UWP 和 WPF 不同,ListView 中绑定的集合修改顺序时,UI 的刷新规则

    2017-10-20 00:14

    walterlv
  • 定义一组抽象的 Awaiter 的实现接口,你下次写自己的 await 可等待对象时将更加方便

    我在几篇文章中都说到了在 .NET 中自己实现 Awaiter 情况。async / await 写异步代码用起来真的很爽,就像写同步一样。然而实现 A...

    walterlv
  • 在 Target 中获取项目引用的所有依赖(dll/NuGet/Project)的路径

    在项目编译成 dll 之前,如何分析项目的所有依赖呢?可以在在项目的 Target 中去收集项目的依赖。

    walterlv
  • 使用腾讯云“自定义监控”监控 GPU 使用率

    本文旨在通过使用腾讯云的“自定义监控”服务来自行实现对 GPU 服务器的 GPU 使用率的监控。

    李想
  • Canvas基础-粒子动画Part2

    紧接上一篇文章 Canvas基础-粒子动画Part1 其实这篇早在一个星期之前就应该发了,无奈事情太多,而且我又跑去写微信公众号了。 粒子动起来 有了上一...

    Bob.Chen
  • 【3D目标检测】谷歌--第一次使用LSTM在稀疏点云中进行3D目标检测

    论文地址: https://arxiv.org/pdf/2007.12392.pdf

    CNNer
  • MySQL中的两种临时表 外部临时表

    通过CREATE TEMPORARY TABLE 创建的临时表,这种临时表称为外部临时表。这种临时表只对当前用户可见,当前会话结束的时候,该临时表会自动关闭。这...

    后端技术探索
  • [译] 理解 JavaScript Mutation 突变和 PureFunction 纯函数

    不可变性、纯函数、副作用,状态可变这些单词我们几乎每天都会见到,但我们几乎不知道他们是如何工作的,以及他们是什么,他们为软件开发带来了什么好处。

    JS菌
  • 可扩展机器学习——线性回归(linear Regression)

    注:这是一份学习笔记,记录的是参考文献中的可扩展机器学习的一些内容,英文的PPT可见参考文献的链接。这个只是自己的学习笔记,对原来教程中的内容进行了梳理,有些图...

    zhaozhiyong
  • 《spss统计分析与行业应用案例详解》实例26非线性回归分析 27加权最小二乘回归分析

    它是一种功能更强大的处理非线性问题的方法,它可以使用户自定义任意形式的函数,从而更加准确地描述变量之间的关系

    统计学家

扫码关注云+社区

领取腾讯云代金券