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.UIElement
的XamlRoot
。
不要使用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?
- XAML Islands – A deep dive – Part 1
- Windows 10 October 2018 Update (SDK 17763)?
- 关键API
- WindowsXamlManager 处理 UWP XAML Framework
- DesktopWindowXamlSource 处理 Content
- 重要NuGet料包
- 必要参考
- XAML Islands – A deep dive – Part 2
- 主要讲了自定义控件的制作
- Announcing Windows Community Toolkit v5.0
- 提到了WindowsXamlHost
- XAML Islands v1 – Updates and Roadmap
- v2会在WinUI3.0中放出。
- .NET的包装器似乎是https://github.com/windows-toolkit/Microsoft.Toolkit.Win32提供的
- A deep-dive into WinUI 3 in desktop apps
- CsWinRT、PInvoke.User32、Full trust desktop apps
(完)