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

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

版權聲明:本做品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、從新發布,但務必保留文章署名呂毅(包含連接:http://blog.csdn.net/wpwalter/),不得用於商業目的,基於本文修改後的做品務必以相同的許可發佈。若有任何疑問,請與我聯繫(walter.lv@qq.com)。 https://blog.csdn.net/WPwalter/article/details/84585431

Windows Community Toolkit 再次更新到 5.0。之前能夠在 WPF 中使用有限的 UWP 控件,而如今有了 WindowsXamlHost,則可使用更多 UWP 原生控件了。css


關於 Windows Community Toolkit 早期版本的 Xaml Bridge,能夠參見:html

安裝 NuGet 包

你須要作的第一步,是在你的 WPF 項目中安裝 Microsoft.Toolkit.Wpf.UI.XamlHost。建議直接在 項目的 NuGet 管理器中搜索並安裝。git

安裝 Microsoft.Toolkit.Wpf.UI.XamlHost

安裝好 NuGet 包後查看引用

配置 WPF 項目能訪問 UWP 的類型

由於咱們即將開始使用到 UWP 中的控件類型,因此須要配置項目可以訪問到 Windows Runtime 的類型。web

添加引用
▲ 添加引用windows

你須要在你的 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

在你添加完這些引用以後,還須要選中這些引用,右擊屬性,把全部的 「複製到本地」 選項設置爲 「否」。markdown

不要複製到本地

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

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

在添加引用時注意選擇 SDK 的版本號
▲ 在添加引用時注意選擇 SDK 的版本號post

添加 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 控件庫。閱讀如下文章瞭解更多:


參考資料

相關文章
相關標籤/搜索