Embedding Native Elements in Skia Apps
Note
This document describes Skia renderer native embedding, for other platforms/renderers see the native views documentation.
In an Uno Platform app with a Skia renderer, i.e. using net9.0-desktop
or adding SkiaRenderer
to the UnoFeatures
MSBuild property, you can embed native controls in your Skia app. This is useful if you want to use a native control for a specific task, for instance, to integrate an existing WPF control.
Each target platform has its own idea of a native element.
Platform | Native element | Description |
---|---|---|
Skia Desktop (Win32) | Uno.UI.NativeElementHosting.Win32NativeWindow | A native Windows window with a unique Hwnd |
Skia Desktop (WPF) | System.Windows.UIElement | A WPF control |
Skia Desktop (X11) | Uno.UI.NativeElementHosting.X11NativeWindow | A native X11 window with a unique XID |
Skia Desktop (macOS) | Not yet supported. | Not yet supported as of Uno Platform 6.0 |
WebAssembly with SkiaRenderer |
Uno.UI.NativeElementHosting.BrowserHtmlElement | An HTML element with a unique id . |
Android with SkiaRenderer |
Android.Views.View | An Android view. |
Apple UIKit with SkiaRenderer |
UIKit.UIView | An UIKit view. |
The app developer is responsible for creating the native element and internal checks make sure that only a supported native element on the running platform is used.
Using embedded native controls
To embed a native element, you will need to set the native control as Content
of a ContentControl
, either via code or XAML. On desktop platforms, it's often more straightforward to create the native element via code since the parameters for creating the native element are not known ahead of time. For example, on Win32, you need to create a native Windows window first, get its Hwnd
and then create a Win32NativeWindow
instance with that Hwnd
value.
Do not set a ContentTemplate
or a ContentTemplateSelector
on the ControlControl
.
Features
The layouting of native elements behaves mostly like regular UIElement
s, using the native platform's measuring and arranging functions, e.g. UIKit.UIView.SizeThatFits
on Apple UIKit, if they are present and defaulting to taking the entire available space on targets that don't have corresponding native measuring and arranging methods.
Furthermore, native elements blend and overlap naturally with Uno controls and respect Z-axis ordering. For example, if you open a popup on top of a native element, the popup will show on top of the element. Native-managed blending is not limited to rectangular boundaries and elements clipped with arbitrary paths work as expected. For example, elements with rounded corners that are placed on a native element will not show up as rectangles but behave as usual with rounded corners.
Setting the Opacity
of the wrapping ContentControl
will also set the opacity of the hosted native element. Likewise, setting the Visibility
of the wrapping ContentControl
will flow to the native element and hide/show it.
Note
As of Uno Platform 6.0, setting the opacity of native elements is not supported on X11.
Limitations
The native control is rendered by the native windowing system and cannot be styled by Uno Platform styles.
While setting the transparency of native elements is supported, native elements don't alpha-blend. In other words, if a partially-transparent Uno control is placed on top of a native element, the native element will not be visible underneath the Uno control. Instead, the transparent area will behave as if the native element is not there and will only show managed Uno controls underneath.
Focus and pointer/keyboard input work as expected most of the time, but, depending on the platform, you might find some quirks with the way inputs are handled.
Placing Uno Controls outside of their layout bounds to be on top of native elements using RenderTransform
or similar techniques will not clip correctly. The clipping of Uno controls is used to calculate which areas are painted by managed controls and how they overlap with native elements. If the clip bounds of a control are unbounded (i.e. the control isn't clipped at all), the clip bounds for managed-native overlapping purposes will be the layout rectangle of the control.