Learning from WPF is still recommended

Host a standard WinRT XAML control in a WPF app using XAML Islands

  • 11 minutes to read

This article demonstrates two ways to use XAML Islands to host a standard WinRT XAML control (that is, a first-party WinRT XAML control provided by the Windows SDK) in a WPF app for the .NET Core 3.1 target platform:

  • It shows how to host the InkCanvas and InkToolbar UWP controls using wrapped controls in the Windows Community Toolkit. These controls encapsulate the interface and functionality of a small subset of useful WinRT XAML controls. You can add them directly to the design surface of your WPF or Windows Forms project and then use them like any other WPF or Windows Forms control in the designer.

  • It also shows how you can host a CalendarView UWP control by using the WindowsXamlHost control in the Windows Community Toolkit. Since only a small subset of the WinRT XAML controls are available in the form of wrapped controls, you can use WindowsXamlHost to host any other standard WinRT XAML control.

This article shows how to host WinRT XAML controls in a WPF app, but the process is similar for a Windows Forms app.

Note

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

Components required

To host a WinRT XAML control in a WPF app (or a Windows Forms app), you need the following components in your solution. This article provides instructions for creating each of these components.

  • Project and source code for your app. Using the WindowsXamlHost control to host custom WinRT XAML controls is currently only supported in apps for the .NET Core 3.x target platform.

  • UWP app project with definition of a root application class derived from XamlApplication. Your WPF or Windows Forms project must have access to an instance of the Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication class provided by the Windows Community Toolkit so that custom UWP XAML controls are discovered and loaded can. The recommended way to do this is to define this object in a separate UWP app project that is not part of the solution for your WPF or Windows Forms app.

    Note

    While the object is not required to host a WinRT first-party XAML control, your app needs this object to support the full range of XAML Islands scenarios, including hosting custom WinRT XAML controls. Therefore, it is recommended that you always define an object in a solution in which you are using XAML Islands.

    Note

    Your solution can only contain one project that defines an object. The project in which the object is defined must contain references to all other libraries and projects that are used to host WinRT XAML controls in XAML Islands.

Create a WPF project

Before you get started, follow these instructions to create a WPF project and configure it to be hosted in XAML Islands. If you have an existing WPF project, you can customize these steps and code samples for your project.

  1. Create a new one in Visual Studio 2019 WPF App (.NET Core) -Project. First, you need to install the latest version of the .NET Core 3.1 SDK if you haven't already.

  2. Make sure package references are enabled:

    1. In Visual Studio, click Tools> NuGet Package Manager> Package Manager Settings.
    2. Make sure the setting Standard format for package management on PackageReference is fixed.
  3. Click the Solution Explorer right-click your WPF project and select Manage NuGet packages out.

  4. Select the tab Search Find the Microsoft.Toolkit.Wpf.UI.Controls package and install the latest stable version. This package contains everything you need to use the wrapped WinRT XAML controls for WPF (including the InkCanvas, InkToolbar, and WindowsXamlHost controls).

  5. Configure your solution for a target platform such as x86 or x64. Most of the XAML Islands scenarios are not supported for projects that target Any CPU use.

    1. Click in Solution Explorer right-click the solution node and select properties -> Configuration properties -> Configuration manager out.
    2. Click below Active solution platform on New.
    3. In the dialog box, choose New solution platform the option x64 or x86 and click OK.
    4. Close the open dialog boxes.

Define a XamlApplication class in a UWP app project

Next, you'll add a UWP app project to your solution and revise the default class in that project to derive from the Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication class that is provided in the Windows Community Toolkit . This class supports the IXamlMetadaraProvider interface, which allows your app to discover and load metadata for custom UWP XAML controls in assemblies in the application's current directory at runtime. This class also initializes the UWP XAML framework for the current thread.

Note

While this step is not required to host a WinRT first-party XAML control, your app needs the object to support the full range of XAML Islands scenarios, including hosting custom WinRT XAML controls. Therefore, it is recommended that you always define an object in a solution in which you are using XAML Islands.

  1. Click in Solution Explorer right-click on the solution node and select Add -> New project out.

  2. Add a project of the type Blank app (Universal Windows) added. Make sure you have both the target version and the minimum required version on Windows 10 Version 1903 (Build 18362) or higher. Also make sure that this new UWP project is not in a subfolder of the WPF project. Otherwise, the WPF app later tries to create the UWP XAML markup as if it were WPF XAML.

  3. In the UWP app project, install the NuGet package Microsoft.Toolkit.Win32.UI.XamlApplication (latest stable version).

  4. Open the file App.xamland replace its contents with the XAML snippet below. Replace with the namespace of your UWP app project.

  5. Open the file App.xaml.csand replace the contents of this file with the code below. Replace with the namespace of your UWP app project.

  6. Delete the file MainPage.xaml from the UWP app project.

  7. Compile the UWP app project.

Add a reference to the UWP project in your WPF project.

  1. Specify the compatible framework version in the WPF project file.

    1. Double-click the Solution Explorer on the WPF project node to open the project file in the editor.

    2. In the first, add PropertyGroupElement, add the following child element. Change the -part of the value as needed to match the values ​​of the target and minimum OS build of the UWP project.

      When you're done, it should PropertyGroupElement look something like this.

  2. Click the Solution Explorer right-click on the node Dependencies under the WPF project and add a reference to your UWP app project.

Instantiating the XamlApplication object in the entry point of your WPF app

Next, you'll add code to the entry point for your WPF app to create an instance of the class that you just defined in the UWP project (this is the class that will now derive from).

  1. Right click on the project node in your WPF project, select Add -> New element and then class out. Name the class Programand click Add.

  2. Replace the generated class with the following code, and then save the file. Replace with the namespace of your UWP app project and with the namespace of your WPF app project.

  3. Right-click the project node and select properties out.

  4. Click the tab application Properties on the drop-down list Start objectand select the fully qualified name of the class that you added in the previous step.

    Note

    By default, WPF projects define an entry point function in a generated code file that is not intended for editing. This step changes the entry point for your project to the method of the new class, which allows you to add code that will run as early as possible in the app's startup phase.

  5. Save your changes to the project properties.

Hosting InkCanvas and InkToolbar using wrapped controls

Now that you've configured your project to use UWP XAML Islands, you can now add the wrapped WinRT XAML controls InkCanvas and InkToolbar to the app.

  1. In your WPF project, open the file MainWindow.xaml.

  2. Add to that WindowElement at the top of the XAML file, add the following attribute. This references the XAML namespace for the wrapped WinRT XAML controls InkCanvas and InkToolbar.

    After adding this attribute, the WindowElement look something like this.

  3. Replace in the file MainWindow.xaml replace the existing element with the following XAML snippet. This creates an InkCanvas and an InkToolbar control (with the ControlsKeyword as a prefix previously defined as a namespace) added to.

    Note

    You can add these and other wrapped controls to the window by removing them from the Windows Community Toolkit in the Toolbox pulling on the designer.

  4. Save the file MainWindow.xaml.

    If you have a digital pen-enabled device - like Surface - and you run this lab on a physical computer, now you could compile and run the app and draw on the screen with the digital pen. However, if you don't have such a device and try to draw with your mouse, nothing happens. This is because the InkCanvas-Control is enabled by default only for input with a digital pen. However, you can change this behavior.

  5. Open the file MainWindow.xaml.cs.

  6. Add the following namespace declaration to the beginning of the file:

  7. Search for the constructor. Add the following line of code after the method and save the code file.

    You can use the default ink behavior with the InkPresenter-Customize the object. This code uses the InputDeviceTypesProperty to enable both mouse and pen input.

  8. Press F5 again to recompile the app and run it in the debugger. If you are using a computer with a mouse, make sure you can draw in the drawing area with the mouse.

Hosting a CalendarView by using the host control

After adding the wrapped WinRT XAML controls InkCanvas and InkToolbar to the app, you can now use the WindowsXamlHost control to add a CalendarView to the app.

  1. Open in Solution Explorer the file MainWindow.xaml.

  2. Add to that WindowElement at the top of the XAML file, add the following attribute. This attribute points to the XAML namespace for the WindowsXamlHost control.

    After adding this attribute, the WindowElement look something like this.

  3. Replace in the file MainWindow.xaml the existing element with the following XAML snippet. This adds a row to the grid and places the WindowsXamlHost object on the last row. To host a CalendarView UWP control, this XAML snippet sets the property to the fully qualified name of the control. It also defines an event handler for the event that is dispatched when the hosted control has been rendered.

  4. Save the file MainWindow.xaml, and open the file MainWindow.xaml.cs.

  5. Add the following namespace declaration to the beginning of the file:

  6. Add the following event handler method to the class and save the code file. When the host control is rendered, this event handler runs and creates a simple event handler for the calendar control event.

  7. Press F5 again to recompile the app and run it in the debugger. Make sure that you can now see the calendar control in the lower part of the window.

Pack the app

You can optionally package the WPF app in an MSIX package for deployment. MSIX is a modern app packaging technology for Windows based on a combination of MSI, APPX, App-V and ClickOnce installation technologies.

The following instructions demonstrate how you can include all of the components in the solution in an MSIX package by using the Packaging Project for Windows Applications option in Visual Studio 2019. These steps are only required if you want to package the WPF app in an MSIX package.

Note

If you are not packing your application in an MSIX package for deployment, computers must have the Visual C ++ runtime installed in order to run your app.

  1. Add a Windows application packaging project to your solution. Choose the same when creating the project Target version and Minimum version as you selected them for the UWP project.

  2. In the package project, right-click the node Applications, and choose Add reference out. From the list of projects, select the WPF project in your solution and click OK.

    Note

    If you want to publish your app to the Microsoft Store, you need to add a reference to the UWP project in the packaging project.

  3. Configure your solution for a target platform such as x86 or x64. This is required in order to package the WPF app in an MSIX package via the “Packaging Project for Windows Applications”.

    1. Click in Solution Explorer right-click on the solution node and select properties -> Configuration properties -> Configuration manager out.
    2. Choose under Active solution platform the option x64 or x86 out.
    3. In the row for your WPF project, select in the column platform the option New out.
    4. Select in the dialog box New solution platform the option x64 or x86 from (the same platform you used for Active solution platform selected) and click OK.
    5. Close the open dialog boxes.
  4. Compile and run the packaging project. Make sure the WPF app is running and the UWP control appears as expected.

Related topics

Is this page helpful?