热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

WindowsXamlHost:在WPF中使用UWP的控件(WindowsCommunityToolkit)

原文WindowsXamlHost:在WPF中使用UWP的控件(WindowsCommunityToolkit)WindowsCommunityToolkit再次更新到5.0

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

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


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

  • WPF 使用 Edge 浏览器 - 林德熙
本文内容
  • 安装 NuGet 包
  • 配置 WPF 项目能访问 UWP 的类型
  • 开始在 WPF 中使用 UWP 的控件
  • 可以忽略的错误
  • 最终效果
  • 值得注意的地方
  • 关于 DPI 适配
  • 更复杂的 UWP 控件嵌入
    • 参考资料

安装 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 事件:

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 的理解和区别,可以参见:

  • Windows 下的高 DPI 应用开发(UWP / WPF / Windows Forms / Win32) - walterlv

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

  • 支持 Windows 10 最新 PerMonitorV2 特性的 WPF 多屏高 DPI 应用开发 - walterlv

更复杂的 UWP 控件嵌入

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

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

  • WindowsXamlHost:在 WPF 中使用 UWP 控件库中的控件 - walterlv

参考资料

  • WindowsXAMLHost control - Windows Community Toolkit - Microsoft Docs
  • Enhance your desktop application for Windows 10 - UWP app developer - Microsoft Docs

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


推荐阅读
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • intellij idea的安装与使用(保姆级教程)
    intellijidea的安装与使用(保姆级教程)IntelliJ在业界被公认为最好的java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(gi ... [详细]
  • 本文介绍了在Mac上安装Xamarin并使用Windows上的VS开发iOS app的方法,包括所需的安装环境和软件,以及使用Xamarin.iOS进行开发的步骤。通过这种方法,即使没有Mac或者安装苹果系统,程序员们也能轻松开发iOS app。 ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了关于apache、phpmyadmin、mysql、php、emacs、path等知识点,以及如何搭建php环境。文章提供了详细的安装步骤和所需软件列表,希望能帮助读者解决与LAMP相关的技术问题。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文讨论了如何在dotnet桌面(Windows)应用程序中添加图标。作者提到可以使用dotnet命令行工具与resource.rc文件一起使用来为标准.NET核心应用程序添加图标。作者还介绍了在创建控制台应用程序时如何编辑projeto1.csproj文件来添加图标。 ... [详细]
  • 如何搭建Java开发环境并开发WinCE项目
    本文介绍了如何搭建Java开发环境并开发WinCE项目,包括搭建开发环境的步骤和获取SDK的几种方式。同时还解答了一些关于WinCE开发的常见问题。通过阅读本文,您将了解如何使用Java进行嵌入式开发,并能够顺利开发WinCE应用程序。 ... [详细]
  • 本文详细介绍了cisco路由器IOS损坏时的恢复方法,包括进入ROMMON模式、设置IP地址、子网掩码、默认网关以及使用TFTP服务器传输IOS文件的步骤。 ... [详细]
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • ShiftLeft:将静态防护与运行时防护结合的持续性安全防护解决方案
    ShiftLeft公司是一家致力于将应用的静态防护和运行时防护与应用开发自动化工作流相结合以提升软件开发生命周期中的安全性的公司。传统的安全防护方式存在误报率高、人工成本高、耗时长等问题,而ShiftLeft提供的持续性安全防护解决方案能够解决这些问题。通过将下一代静态代码分析与应用开发自动化工作流中涉及的安全工具相结合,ShiftLeft帮助企业实现DevSecOps的安全部分,提供高效、准确的安全能力。 ... [详细]
  • 本文介绍了Android平台各个版本的API级别、版本号以及平台亮点,从Android 1.0到Android 10.0,共涵盖了多个版本的特点和发展历程。详细内容请参考https://developer.android.google.cn/guide/topics/manifest/uses-sdk-element.html。 ... [详细]
author-avatar
min-章_998
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有