Skip to content

Hosting a WinForms Control in WPF

In this article I will show you how to host a WinForms Control inside a WPF View.

Introduction

Hosting a WinForms Control in your WPF view is quite easy and takes just a few steps. Therefore, Microsoft provides the class WindowsFormsHost to embed the Form inside your WPF view. For demonstration I will add a standard WinForms Button to a WPF view and rise an WPF Popup Dialog when the button is pushed. You can host a custom WinForms Controls in the same way.

Hosting a WinForms Control in XAML

1. Add a reference to WindowsFormsIntegration.dll in your WPF project.

That assembly contains the definition of WindowsFormsHost which will be needed to host the WinForms Control.

2. Add a reference to System.Windows.Forms.dll in your WPF project.

As I want to show you how to host a WinForms Button I need to reference the dll which contains the definition of the WinForms Button. If you want to host a WinForms Control of your own Controls Library you need to reference that assembly instead.

3. Embed the Button inside the View

To embed the Button we need to declare the WindowsFormsHost at the desired place and wrap the WinForms Control.

<Window x:Class="HostingWinFormsInsideWpfDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:HostingWinFormsInsideWpfDemo" xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <StackPanel> <WindowsFormsHost> <wf:Button Click="Button_Click" Text="Push me!"/> </WindowsFormsHost> </StackPanel> </Window>
Code language: HTML, XML (xml)

You can use the WinForms Control very similar to a simple WPF Control. You can declare it in xaml, add event handlers and set properties.

However, inside the WindowsFormsHost a completely different world starts.

  1. There is no Data Context available
  2. You cannot set bindings or styles to properties as they are just simple .Net properties. Styles and bindings can only be applied to dependency properties what is a WPF technology.
  3. You cannot declare other WPF Controls inside WindowsFormsHost.
  4. The WindowsFormsHost (and the Button) has its own window handle and will be drawn on top of each other WPF Control which overlaps it. The WPF z-order inside the WPF panel has no influence on it. This, for example, leads to serious problems when a WinForms host is used inside a WPF ScrollViewer. Please see my artice ‘Airspace Problem’ to learn more about it.

You can add an event handler of the WinForms Button Click event into your WPF Window code behind file in the same way as for a WPF Button.

using System; using System.Windows; namespace HostingWinFormsInsideWpfDemo { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Forms_Button_Click(object sender, EventArgs e) { MessageBox.Show("WinForms Button pushed!"); } } }
Code language: C# (cs)

Hosting a WinForms Control in Code

The following listing shows how to add a WinForms Control in code to a WPF View.

using System; using System.Windows; using System.Windows.Forms.Integration; namespace HostingWinFormsInsideWpfDemo { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var formsHost = new WindowsFormsHost(); var formsButton = new System.Windows.Forms.Button(); formsButton.Text = "Push me!"; formsButton.Click += Forms_Button_Click; formsHost.Child = formsButton; stackPanel.Children.Add(formsHost); } private void Forms_Button_Click(object sender, EventArgs e) { MessageBox.Show("WinForms Button pushed!"); } } }
Code language: C# (cs)

Copyright (c) by Thomas Kemp, 2021