Windows
Overview
Windows is the native platform for WPF, and XPF applications run on Windows with full compatibility. This page covers Windows-specific considerations when using XPF rather than standard WPF.
Win32 API behavior
When Win32 API shims are enabled on Windows, calls are routed through the XPF shim layer rather than directly to the native Win32 APIs. This ensures consistent behavior with non-Windows platforms during development and testing.
If you need to call native Win32 APIs directly (bypassing the shim), place those calls in a separate assembly and exclude it from the shim:
AvaloniaUI.Xpf.WinApiShim.WinApiShimSetup.AutoEnable(asm =>
{
if (asm.GetName().Name == "MyNativeWindowsInterop")
return true; // skip this assembly
return false;
});
WinForms hosting
XPF can host WinForms controls on Windows. Enable this by adding the following to a Windows-conditional property group:
<PropertyGroup Condition="$([MSBuild]::IsOSPlatform('Windows'))">
<XpfUseMicrosoftWindowsForms>true</XpfUseMicrosoftWindowsForms>
</PropertyGroup>
This disables XPF's WinForms shim layer and enables native WinForms integration. WinForms hosting is only available on Windows; condition the property group to avoid build failures on other platforms.
STA threading
Some Windows operations require the main thread to be marked as STA (Single-Threaded Apartment):
- Clipboard operations via COM
- OLE drag and drop
- Certain third-party COM components
If you encounter COMException: CoInitialize was not called, add the [STAThread] attribute to your entry point. When using custom initialization, XPF handles this automatically.
CefSharp
CefSharp.Wpf.NetCore works with XPF on Windows. If CursorInteropHelper.Create() throws a NotImplementedException, upgrade to XPF 1.6.0 or later.
For older XPF versions, work around the issue by deriving from ChromiumWebBrowser and overriding OnCursorChange:
protected override void OnCursorChange(object sender, CursorChangeEventArgs e)
{
// Map CefSharp cursor types to WPF Cursors
var cursor = e.CursorType switch
{
CefCursorType.Hand => Cursors.Hand,
CefCursorType.IBeam => Cursors.IBeam,
CefCursorType.Cross => Cursors.Cross,
CefCursorType.Wait => Cursors.Wait,
_ => Cursors.Arrow
};
Cursor = cursor;
}
For cross-platform browser embedding, see Web Content Embedding.
Window handles
XPF uses virtual window handles for WPF API calls such as WindowInteropHelper.Handle. On Windows, these are real HWNDs. To access the underlying handle directly, use the Avalonia interop API:
using Atlantis;
var avaloniaWindow = XpfWpfAbstraction.GetAvaloniaWindowForWindow(myWpfWindow);
var handle = avaloniaWindow.TryGetPlatformHandle();
// handle.Handle is the native HWND on Windows
See Native Window Handles for more details.
Deployment
See Windows Deployment for publishing, packaging, and installer guidance.