In part 2 of this article series I’ve shown using the Desktop Bridge – using Windows Runtime APIs and integrating communication with UWP applications with WPF. One limitation of the desktop bridge is that new UWP controls can’t be used directly in the WPF application. Using the desktop bridge, new user interface features are used with the UWP application, and communication is done between the WPF and the UWP application using app services. This all has been shown in the previous article.
Another integration level is offered with XAML Islands. Here, the new UWP controls can be directly used with the WPF application – running in the same process on the same thread. This article gives you more information about features and issues on using XAML Islands.
UWP XAML Hosting API
Starting with the Windows 10 October 2018 update (build 17763), Windows 10 offers a new API – the UWP XAML hosting API. This API can be used in desktop applications and allows to associate UWP XAML controls with window handles (HWND). This makes it possible to use UWP controls with Win32 applications, e.g. native C++ applications as well as WPF and Windows Forms applications.
Be aware that with the Windows 10 October 2018 update, this API is in developer preview and not recommended to be used in production.
WindowsXamlManager allows to initialize the current thread to host UWP controls (
InitializeForCurrentThread). The class
DesktopWindowXamlSource is then used for hosting the controls. To the
Content property, a
Windows.UI.Xaml.UIElement derived class can be assigned to. This class then allows setting the focus, and receiving focus events.
An important WPF class in this scenario is the
HwndHost class. This class is a WPF
FrameworkElement (derives from the base class
FrameworkElement), and allows to host a Window in a WPF application. This class is available since the first version of WPF – starting with .NET Framework 3.0.
Windows Forms and WPF had a similar interop scenario. You can host Windows Forms controls in WPF, and the other way around – WPF controls in Windows Forms apps. Here, the restriction is the airspace: one pixel – one technology. You can’t have a transparent WPF control and let Windows Forms shine-through. This way, you also can’t use non-rectangular controls. The same restriction applies now hosting UWP controls in WPF applications.
Enhancing WPF applications, there’s no need to use this API directly. Instead, you can use the features wrapped controls and host controls which are part of the Windows Community Toolkit.
Windows Community Toolkit
Wrappers to UWP controls that can be used directly with a WPF application can be found in the Windows Community Toolkit (the NuGet package has the name Microsoft.Toolkit), previously known as UWP Community Toolkit. This toolkit was first developed to create additional controls for UWP applications. Because of its change to also support WPF and Windows Forms applications, the name was changed from UWP Community Toolkit to Windows Community Toolkit. The name of the packages start with Microsoft.Toolkit. The packages offering support for WPF applications, are listed here:
The Controls package includes wrapper controls for inking including
InkToolbar, several ink button controls for the toolbar, and the MediaPlayerElement to play videos. The WebView package contains the
WebView class which makes use of Microsoft Edge running on Windows 10. This package also includes
WebViewCompatible supports more versions of the Windows platform: using this control with Windows 10 devices, it uses the rendering engine of Microsoft Edge. On older Windows systems, Internet Explorer‘s engine is used.
The XamlHost package is the foundation used by the other packages – and it allows you to host other UWP controls in WPF.
To access the Windows API from UWP you also need to reference the Windows Runtime APIs as shown in Enhance your desktop application for Windows 10.
Let’s start with wrapped controls – controls that are built for WPF and access UWP controls behind the scenes. One of these controls is the
WebView control – available in the namespace
Microsoft.ToolKit.Wpf.UI.Controls. For using this control within XAML code, the namespace together with the assembly needs to be added to the XML declaration to map the .NET namespace to XML. This can easily be done using the Visual Studio toolbox and moving the controls to the XAML code. As soon, as the NuGet packages are added, the controls show up in the toolbox.
Adding references to the NuGet packages, the
WebView can be used as shown in the following code snippet.
The sample application also includes a Ribbon control that’s used to navigate with the WebView. Commands map to handler methods, and the methods access the WebView control for the navigation.
The sample application with the Ribbon control and the Web View is shown here:
Other wrapped control are
InkCanvas. The canvas allows to draw ink while the toolbar control offers selecting pen, pencil, highlighter, eraser, and a ruler. The toolbar is connected to the canvas setting the
To draw not only with a pen, but also with mouse and touch, the
InputDeviceTypes property of the
InkPresenter can be configured for the enum values
InkPresenter as well as the
CoreInputDeviceTypes enum has been wrapped with WPF classes.
Running the application, you can select pen, pencil, and the highlighter to draw an image into the canvas. The ruler helps drawing straight lines.
MapControl makes use of the UWP
MapControl. This control offers maps with different styles such as aerial, terrain, and road styles, offers street views, and can show landmarks and traffic information.
With the XAML code using the
MapControl, properties such as
LandmarksVisible are set.
The position of the map is set in the code-behind invoking the method
TrySetViewAsync method of the
An alternative to use the UWP MapControl is to use the new Azure Maps Map Control. This can be used with HTML pages – with WPF, the wrapped
WebViewcan be used to host this control.
Instead of using the predefined wrapped controls, you can host other controls. The sample application makes use of the UWP
WindowsXamlHost class (in the namespace
Microsoft.Toolkit.Wpf.UI.XamlHost and the package
Microsoft.Toolkit.Wpf.UI.XamlHost) hosts a UWP control by setting the
InitialTypeName property to the name of the UWP class.
To access the underlying UWP control, a handler to the
ChildChanged event can be defined. The
Child property of the
WindowsXamlHost is of type
Windows.UI.Xaml.UIElement. This returns the UWP control, with is a
Windows.UI.Xaml.Controls.Button with the code sample. This can now be used to access the members of the button, such as setting the
Content property and a handler for the
Compared to the desktop bridge, the XAML Island offers another integration level: you can use UWP controls within WPF applications. You can enhance existing WPF applications with new controls available with the UWP platform, and make use of new design features. The best way to create new desktop applications nowadays is using the Universal Windows Platform. Using the XAML Island allows enhancing your WPF application with new Windows 10 features.
An even better integration is coming with .NET Core 3.0 which allows enhancing WPF applications with new features from .NET Core – which also will support XAML islands.
In case you would like to enhance your WPF applications now – go ahead and use Windows Runtime APIs with the help of the desktop bridge.
If this information motivated you enhancing your WPF applications with UWP features, consider buying me a coffee which helps me staying up longer and writing more articles.
Enjoy learning and programming!
Important links for the article:
GitHub repository for the Windows Community Toolkit
Current issues with XAML islands
Microsoft Docs – Using the UWP XAML hosting API in a desktop application
Microsoft Docs – UWP Controls in Desktop Applications
Microsoft Docs – Windows UI Xaml Hosting