原文 WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit)html
Windows Community Toolkit 再次更新到 5.0。之前能够在 WPF 中使用有限的 UWP 控件,而如今有了 WindowsXamlHost,则可使用更多 UWP 原生控件了。git
关于 Windows Community Toolkit 早期版本的 Xaml Bridge,能够参见:windows
你须要作的第一步,是在你的 WPF 项目中安装 Microsoft.Toolkit.Wpf.UI.XamlHost。建议直接在 项目的 NuGet 管理器中搜索并安装。浏览器
由于咱们即将开始使用到 UWP 中的控件类型,因此须要配置项目可以访问到 Windows Runtime 的类型。app
▲ 添加引用post
你须要在你的 WPF 项目中添加如下 6 个引用才能访问 UWP 的类型:spa
在你添加完这些引用以后,还须要选中这些引用,右击属性,把全部的 “复制到本地” 选项设置为 “否”。设计
▲ 添加 Windows Runtime 的 .NET Framework 类型引用3d
▲ 添加 Windows.WinMD 的引用code
▲ 在添加引用时注意选择 SDK 的版本号
▲ 添加 Windows.Foundation.UniversalApiContract.winmd
▲ 添加 Windows.Foundation.FoundationContract.winmd
你能够像使用普通 WPF 控件同样将 WindowsXamlHost 添加到你的 WPF 界面中:
▲ 添加 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) { }
在启动的时候,你可能会遇到一些异常。好比下面这个:
由于咱们不是原生的 UWP,而是 Host 在 WPF 中的 UWP 控件,因此会没有 Application
。这在 UWP 控件初始化内部已经 catch
了,因此你能够忽略。
当将程序跑起来以后,你就能看到 WPF 窗口中的 UWP 控件了。
为了让 UWP 控件可以在 WPF 窗口中得到正确的 Per-Monitor 的 DPI 适配效果,你须要设置为 PerMonitorV2 的 DPI 感知级别。
在 PerMonitorV2 的 DPI 感知级别下,UWP 控件可以正常得到 DPI 缩放。
在 100% DPI 的屏幕下:
在 150% DPI 的屏幕下:
而若是只是指定为 PerMonitor,那么切换 DPI 或者切换屏幕的时候,只有 WPF 部分会缩放,而 UWP 部分不会变化。
关于 PerMonitorV2 和 PerMonitor 的理解和区别,能够参见:
关于如何在 WPF 下开启 PerMonitorV2 级别的 DPI 感知能够参见:
若是但愿将更多的 WPF 窗口内的 UI 部分交给 UWP 来作,那么就不能只是仅仅初始化一个 Button
就完了。
你须要引入一个 UWP 控件库。阅读如下文章了解更多:
本文会常常更新,请阅读原文: https://walterlv.com/post/use-uwp-controls-in-wpf.html ,以免陈旧错误知识的误导,同时有更好的阅读体验。