WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit)

简介: 原文 WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit) Windows Community Toolkit 再次更新到 5.0。

原文 WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit)

Windows Community Toolkit 再次更新到 5.0。以前可以在 WPF 中使用有限的 UWP 控件,而现在有了 WindowsXamlHost,则可以使用更多 UWP 原生控件了。


关于 Windows Community Toolkit 早期版本的 Xaml Bridge,可以参见:

安装 NuGet 包

你需要做的第一步,是在你的 WPF 项目中安装 Microsoft.Toolkit.Wpf.UI.XamlHost。建议直接在 项目的 NuGet 管理器中搜索并安装。

安装 Microsoft.Toolkit.Wpf.UI.XamlHost

安装好 NuGet 包后查看引用

配置 WPF 项目能访问 UWP 的类型

因为我们即将开始使用到 UWP 中的控件类型,所以需要配置项目能够访问到 Windows Runtime 的类型。

添加引用
▲ 添加引用

你需要在你的 WPF 项目中添加以下 6 个引用才能访问 UWP 的类型:

  • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5
    • 引用 System.Runtime.WindowsRuntime
    • 引用 System.Runtime.WindowsRuntime.UI.Xaml
    • 引用 System.Runtime.InteropServices.WindowsRuntime
  • C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Facade
    • 引用 Windows.winmd
  • C:\Program Files (x86)\Windows Kits\10\References\
    • 在此目录下选择你的 SDK 版本(如 16299,17763 等)
      • Windows.Foundation.UniversalApiContract\
        • 在此目录下选择你的 API 版本(如 4.0.0.0)
          • 引用 Windows.Foundation.UniversalApiContract.winmd
      • Windows.Foundation.FoundationContract
        • 在此目录下选择你的 API 版本(如 3.0.0.0)
          • 引用 Windows.Foundation.FoundationContract.winmd

在你添加完这些引用之后,还需要选中这些引用,右击属性,把所有的 “复制到本地” 选项设置为 “否”。

不要复制到本地

添加 Windows Runtime 的 .NET Framework 类型引用
▲ 添加 Windows Runtime 的 .NET Framework 类型引用

添加 Windows.WinMD 的引用
▲ 添加 Windows.WinMD 的引用

在添加引用时注意选择 SDK 的版本号
▲ 在添加引用时注意选择 SDK 的版本号

添加 Windows.Foundation.UniversalApiContract.winmd
▲ 添加 Windows.Foundation.UniversalApiContract.winmd

添加 Windows.Foundation.FoundationContract.winmd
▲ 添加 Windows.Foundation.FoundationContract.winmd

开始在 WPF 中使用 UWP 的控件

你可以像使用普通 WPF 控件一样将 WindowsXamlHost 添加到你的 WPF 界面中:

  • 拖拽到界面设计器中
  • 拖拽到 XAML 代码行中
  • 直接在 XAML 代码中写

添加 WindowsXamlHost 控件
▲ 添加 WindowsXamlHost 控件

接着,指定 InitialTypeName 属性为 UWP 中的控件的名称(带命名空间)。这样,当 WindowsXamlHost 初始化的时候,也会初始化一个 UWP 的控件。

这里为了简单,我初始化一个 UWP 的按钮。但必须得为 UWP 的按钮进行一些初始化,所以我监听了 ChangedChanged 事件:

<XamlHost:WindowsXamlHost Grid.Column="1"
    InitialTypeName="Windows.UI.Xaml.Controls.Button" ChildChanged="WindowsXamlHost_ChildChanged" /> 
private void WindowsXamlHost_ChildChanged(object sender, EventArgs e) { var host = (WindowsXamlHost) sender; var button = (Windows.UI.Xaml.Controls.Button) host.Child; button.Width = 120; button.Height = 40; button.Content = "walterlv.com"; button.Click += UwpButton_Click; } private void UwpButton_Click(object sender, RoutedEventArgs e) { } 

可以忽略的错误

在启动的时候,你可能会遇到一些异常。比如下面这个:

没有 Application

因为我们不是原生的 UWP,而是 Host 在 WPF 中的 UWP 控件,所以会没有 Application。这在 UWP 控件初始化内部已经 catch 了,所以你可以忽略。

最终效果

当将程序跑起来之后,你就能看到 WPF 窗口中的 UWP 控件了。

运行效果

值得注意的地方

  1. 目前 WindowsXamlHost 还不够稳定,会出现一些闪退
    • 这点就需要为 WindowsCommunityToolkit 贡献 Issues 或代码了
  2. Host 的 UWP 控件是一个新的 HwndSource,这相当于 UWP 的控件是通过子窗口的形式与 WPF 窗口放在一起的
    • 于是,只能指定一个矩形区域完全属于 UWP,在这个区域 WPF 控件无法与其获得交互或渲染叠加

关于 DPI 适配

为了让 UWP 控件能够在 WPF 窗口中获得正确的 Per-Monitor 的 DPI 适配效果,你需要设置为 PerMonitorV2 的 DPI 感知级别。

在 PerMonitorV2 的 DPI 感知级别下,UWP 控件能够正常获得 DPI 缩放。

在 100% DPI 的屏幕下:

100% DPI 下

在 150% DPI 的屏幕下:

PerMonitorV2 感知级别 150% DPI 下

而如果只是指定为 PerMonitor,那么切换 DPI 或者切换屏幕的时候,只有 WPF 部分会缩放,而 UWP 部分不会变化。

PerMonitor 感知级别 150% DPI 下

关于 PerMonitorV2 和 PerMonitor 的理解和区别,可以参见:

关于如何在 WPF 下开启 PerMonitorV2 级别的 DPI 感知可以参见:

更复杂的 UWP 控件嵌入

如果希望将更多的 WPF 窗口内的 UI 部分交给 UWP 来做,那么就不能只是仅仅初始化一个 Button就完了。

你需要引入一个 UWP 控件库。阅读以下文章了解更多:


参考资料

本文会经常更新,请阅读原文: https://walterlv.com/post/use-uwp-controls-in-wpf.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

目录
相关文章
|
4月前
|
API 开发工具 UED
在 UWP 中使用 Windows App SDK
【10月更文挑战第17天】在UWP中使用Windows App SDK可增强应用功能和性能。首先了解SDK特性,接着安装Visual Studio 2022及以上版本,并从微软官网下载安装SDK。配置项目时,确保目标版本支持SDK,添加SDK引用后即可使用新API提升应用体验。开发过程中应充分利用调试工具进行测试,确保应用的兼容性和稳定性。
|
6月前
|
vr&ar C# 图形学
WPF与AR/VR的激情碰撞:解锁Windows Presentation Foundation应用新维度,探索增强现实与虚拟现实技术在现代UI设计中的无限可能与实战应用详解
【8月更文挑战第31天】增强现实(AR)与虚拟现实(VR)技术正迅速改变生活和工作方式,在游戏、教育及工业等领域展现出广泛应用前景。本文探讨如何在Windows Presentation Foundation(WPF)环境中实现AR/VR功能,通过具体示例代码展示整合过程。尽管WPF本身不直接支持AR/VR,但借助第三方库如Unity、Vuforia或OpenVR,可实现沉浸式体验。例如,通过Unity和Vuforia在WPF中创建AR应用,或利用OpenVR在WPF中集成VR功能,从而提升用户体验并拓展应用功能边界。
135 1
|
6月前
|
开发者 C# Windows
WPF与游戏开发:当桌面应用遇见游戏梦想——利用Windows Presentation Foundation打造属于你的2D游戏世界,从环境搭建到代码实践全面解析新兴开发路径
【8月更文挑战第31天】随着游戏开发技术的进步,WPF作为.NET Framework的一部分,凭借其图形渲染能力和灵活的UI设计,成为桌面游戏开发的新选择。本文通过技术综述和示例代码,介绍如何利用WPF进行游戏开发。首先确保安装最新版Visual Studio并创建WPF项目。接着,通过XAML设计游戏界面,并在C#中实现游戏逻辑,如玩家控制和障碍物碰撞检测。示例展示了创建基本2D游戏的过程,包括角色移动和碰撞处理。通过本文,WPF开发者可更好地理解并应用游戏开发技术,创造吸引人的桌面游戏。
309 0
|
6月前
|
C# Windows 开发者
当WPF遇见OpenGL:一场关于如何在Windows Presentation Foundation中融入高性能跨平台图形处理技术的精彩碰撞——详解集成步骤与实战代码示例
【8月更文挑战第31天】本文详细介绍了如何在Windows Presentation Foundation (WPF) 中集成OpenGL,以实现高性能的跨平台图形处理。通过具体示例代码,展示了使用SharpGL库在WPF应用中创建并渲染OpenGL图形的过程,包括开发环境搭建、OpenGL渲染窗口创建及控件集成等关键步骤,帮助开发者更好地理解和应用OpenGL技术。
478 0
|
6月前
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
103 0
|
6月前
|
API C# Shell
WPF与Windows Shell完美融合:深入解析文件系统操作技巧——从基本文件管理到高级Shell功能调用,全面掌握WPF中的文件处理艺术
【8月更文挑战第31天】Windows Presentation Foundation (WPF) 是 .NET Framework 的关键组件,用于构建 Windows 桌面应用程序。WPF 提供了丰富的功能来创建美观且功能强大的用户界面。本文通过问题解答的形式,探讨了如何在 WPF 应用中集成 Windows Shell 功能,并通过具体示例代码展示了文件系统的操作方法,包括列出目录下的所有文件、创建和删除文件、移动和复制文件以及打开文件夹或文件等。
135 0
|
6月前
|
C# Windows 监控
WPF应用跨界成长秘籍:深度揭秘如何与Windows服务完美交互,扩展功能无界限!
【8月更文挑战第31天】WPF(Windows Presentation Foundation)是 .NET 框架下的图形界面技术,具有丰富的界面设计和灵活的客户端功能。在某些场景下,WPF 应用需与 Windows 服务交互以实现后台任务处理、系统监控等功能。本文探讨了两者交互的方法,并通过示例代码展示了如何扩展 WPF 应用的功能。首先介绍了 Windows 服务的基础知识,然后阐述了创建 Windows 服务、设计通信接口及 WPF 客户端调用服务的具体步骤。通过合理的交互设计,WPF 应用可获得更强的后台处理能力和系统级操作权限,提升应用的整体性能。
172 0
|
6月前
|
C# Windows 开发者
超越选择焦虑:深入解析WinForms、WPF与UWP——谁才是打造顶级.NET桌面应用的终极利器?从开发效率到视觉享受,全面解读三大框架优劣,助你精准匹配项目需求,构建完美桌面应用生态系统
【8月更文挑战第31天】.NET框架为开发者提供了多种桌面应用开发选项,包括WinForms、WPF和UWP。WinForms简单易用,适合快速开发基本应用;WPF提供强大的UI设计工具和丰富的视觉体验,支持XAML,易于实现复杂布局;UWP专为Windows 10设计,支持多设备,充分利用现代硬件特性。本文通过示例代码详细介绍这三种框架的特点,帮助读者根据项目需求做出明智选择。以下是各框架的简单示例代码,便于理解其基本用法。
314 0
|
6月前
|
C# 开发者 Windows
WPF在.NET9中的重大更新:Windows 11 主题
WPF在.NET9中的重大更新:Windows 11 主题
72 0
|
7月前
|
C# 开发者 Windows
WPF在.NET9中的重大更新:Windows 11 主题
这也是一个很好的学习WPF的项目,可以通过看源代码提升自己的WPF水平。 WPF Gallery演示如何在标记中指定 XAML 控件,因为每个控件页都显示用于创建每个示例的标记。它还将显示您的应用程序的所有可能的布局选项。 WPF Gallery应用还包含有关使用颜色、排版和图标开发特殊应用程序的设计指南。它还包括一个示例页,用于演示如何使用不同的控件在 WPF 应用程序中创建用户界面。 WPF在.NET 9中可以使用Win11主题的控件了,有助于WPF开发者们开发出更符合现在设计风格、更美观的界面。 希望WPF越来越好。
94 0