Host WinRT XAML controls in desktop apps (XAML Islands)

Win10 1903k开始,可以在非UWP的桌面应用中使用XAML Islands。也就是在Win32的GUI中部分使用WinRT的XAML元素。

XAML Islands可以寄宿任何Windows.UI.Xaml.UIElement派生出来的类型,包括

  • 大多数Windows SDK提供的XAML控件,以及WinUI 2料库。
  • 任意自定义的XAML控件,但是需要从源码编译进目标程序

Windows Community Toolkit也提供了一些适用于XAML Island的控件

XAML Islands是通过WinRT XAML hosting API实现的。

Requirements

  • 操作系统Win10 1903或以后
  • 如果应用没有打包成MSIX,那么机子上必须装有Visual C++ Runtime

WPF and Windows Forms applications

对于WPF和WinForms,有两个不同XAML控件集合可以用:wrappered contorls和host controls。

Using XAML Islands to host WinRT XAML controls in WPF and Windows Forms apps is currently supported only in apps that target .NET Core 3.x. XAML Islands are not yet supported in apps that target .NET 5, or in apps that any version of the .NET Framework.

Wrapped controls

某些WinRT XAML控件包装以后形成的,表现得像WPF或者WinForms控件。

这些控件包括

  • InkCanvas
  • InkTookbar
  • MediaPlayerElement
  • MapControl

Host controls

可以使用Windows Community Toolkit提供的WindowsXamlHost控件。

Configure your project to use the XAML Island .NET controls

需要安装某些NuGet料包(版本必须是6.0.0或以上)

  • Wrapped controls
    • WPF: Microsoft.Toolkit.Wpf.UI.Controls
    • WinForms: Microsoft.Toolkit.Forms.UI.Controls
  • Host control
    • WPF: Microsoft.Toolkit.Wpf.UI.XamlHost
    • Windows Forms: Microsoft.Toolkit.Forms.UI.XamlHost

宿寄自定义的WinRT XAML控件的话,需要一些额外的操作。

Web view controls

……

C++ desktop (Win32) applications

The WinRT XAML hosting API consists of several Windows Runtime classes and COM interfaces that your C++ desktop application can use to host any WinRT XAML control that derives from Windows.UI.Xaml.UIElement.

Windows Community Toolkit提供的WindowsXamlHost提供的必要的适配,方便使用。

Architecture of XAML Islands

……

Limitations and workarounds

Supported only with workarounds

WinUI2料库在XAML Island的使用是有条件的。MSIX打包的可以使用prerelease或者release版本的Microsoft.UI.Xaml,非打包的只能使用prerelease(或使用Dynamic Dependencies API

需要使用XamlRoot,而不是CoreWindow、ApplicationView或者Window标类去访问XAML的树根。

支持https://docs.microsoft.com/en-us/windows/uwp/app-to-app/share-data的话,必须使用IDataTransferManagerInterop来获取DataTransferManager标的,用于初始化分享操作。一个WPF的示例https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/ShareSource

在XAML Islands中使用x:Bind是不受支持的,需要在一个 .NET Standard library声明数据模型。

Not supported

  • 对于WPF或者WinForms,只支持.NET Core 3.x或之后的版本
  • 寄宿的XAML控件无法响应系统主题的明暗变化,但是能响应高对比度变化
  • 媒体播放无法全屏
  • 不支持handwriting view
  • 不支持@Places@People的文本控件
  • 不支持ContentDialog中包含文本输入,比如TextBox、RichEditBox、AutoSuggestBox等。一个变通的办法是使用Popup。
  • 不支持在Windows.UI.Xaml.Controls.Image或者Windows.UI.Xaml.Media.Imaging.SvgImageSource中使用SVG

Window host context for XAML Islands

多个XAML Islands可能寄宿在同一个线程,需要使用XamlRoot来访问这些树的根部。Windows.UI.Xaml.UIElementXamlRoot

不要使用CoreWindows.Bounds

Additional resources

示例参考https://github.com/microsoft/Xaml-Islands-Samples

Use XAML Islands to host a UWP XAML control in a C# WPF app

要求.NET Core 3,在.NET 6中无法使用,欸。

其他

https://github.com/microsoft/Xaml-Islands-Samples

Microsoft.Windows.SDK.Contracts在.NET 5或以后都不能使用了,WinRT的Winmd需要通过C#WinRT来耗用。 <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">要改成? https://stackoverflow.com/questions/61733750/wpf-project-integrating-a-uwp-xaml-island-gridview https://github.com/nesherhh/XamlIslandsNET5

https://visualstudiomagazine.com/articles/2021/01/11/xaml-net5.aspx How Does .NET 5 Do XAML? By Decoupling It from Windows with WinUI 3, C#/WinRT and More

I can use XAML Islands in WPF just if the .NET Core is the target platform?

(完)