Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

.NET

WPF Interoperability


Embedding Windows Forms Controls In WPF Applications

You've seen that WPF can host Win32 controls by wrapping any HWND inside an HwndHost. And Windows Forms controls can easily be exposed as Win32 controls. (Unlike WPF controls, they are all HWND-based, so System.Windows.Forms.Control directly defines a Handle property exposing the HWND.) Therefore, you could imagine using the same techniques previously discussed to host Windows Forms controls inside WPF.

However, there is the opportunity for much richer integration between Windows Forms and WPF, without delving into the underlying HWND-based plumbing. Sure, they have different rendering engines and different controls. But they both have rich .NET-based object models with similar properties and events, and both have services (such as layout and data binding) that go above and beyond their Win32 common denominator.

Indeed, WPF takes advantage of this opportunity and also has built-in functionality for direct interoperability with Windows Forms. This support is still built on top of the Win32 HWND interoperability described in the last two sections, but with many features to make the integration much simpler. The hard work is done for you, so you can communicate more directly between the technologies, usually without the need to write any unmanaged code.

As with Win32 interoperability, WPF defines a pair of classes to cover both directions of communication. The analog to HwndHost is called WindowsFormsHost, and appears in the System.Windows.Forms.Integration namespace (in the WindowsFormsIntegration.dll assembly).

Embedding a PropertyGrid with Procedural Code

Windows Forms has several interesting built-in controls that WPF lacks in its first version. One control--the powerful PropertyGrid--helps to highlight the deep integration between Windows Forms and WPF, so let's use that inside a WPF Window. (Of course, you can also create custom Windows Forms controls and embed them in WPF Windows as well.)

The first step is to add a reference to System.Windows.Forms.dll and WindowsFormsIntegration.dll to your WPF-based project. After you've done this, your Window's Loaded event is an appropriate place to create and attach a hosted Windows Forms control. For example, let's take a simple Window containing a Grid called grid:

<Window x:Class=.Window1"
 xmlns=://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x=://schemas.microsoft.com/winfx/2006/xaml"
 Title=a Windows Forms Property Grid in WPF"
 Loaded=_Loaded">
  private void Window_Loaded(object sender, RoutedEventArgs e)
{ 
 // Create the host and the PropertyGrid control
 System.Windows.Forms.Integration.WindowsFormsHost host =
  new System.Windows.Forms.Integration.WindowsFormsHost();
 System.Windows.Forms.PropertyGrid propertyGrid =
  new System.Windows.Forms.PropertyGrid();

 // Add the PropertyGrid to the host, and the host to the WPF Grid
 host.Child = propertyGrid;
 grid.Children.Add(host);

 // Set a PropertyGrid-specific property
 propertyGrid.SelectedObject = this;
} 

The integration-specific code is as simple as instantiating WindowsFormsHost and setting its Child property to the desired object. WindowsFormsHost's Child property can be set to any object that derives from System.Windows.Forms.Control.

The last line, which sets PropertyGrid's SelectedObject property to the instance of the current WPF Window, enables a pretty amazing scenario. PropertyGrid displays the properties of any .NET object, and, in some cases, enables the editing of the object's values. It does this via .NET reflection. Because WPF objects are .NET objects, PropertyGrid provides a fairly rich way to edit the current Window's properties on-the-fly without writing any extra code. Figure 7 shows the previously defined Window in action. When running this application, you can see values change as you resize the Window, you can type in new property values to resize the Window, you can change its background color or border style, and so on. (The WindowsFormsHost class actually derives from HwndHost, so it supports the same HWND interoperability features described earlier, just in case you want to dig into lower-level mechanics, such as overriding its WndProc method.)

[Click image to view at full size]
Figure 7: The hosted Windows Forms PropertyGrid enables you to change properties of the WPF Window on the fly.

Notice that the enumeration values for properties such as HorizontalContent Alignment are automatically populated in a drop-down list, thanks to the standard treatment of .NET enums. But Figure 7 highlights some additional similarities between Windows Forms and WPF, other than being .NET-based. Notice that Window's properties are grouped into categories such as "Behavior," "Content," and "Layout." This comes from CategoryAttribute markings that are used both by Windows Forms and WPF. The type converters used by WPF are also compatible with Windows Forms, so you can type in "red" as a color, for example, and it gets automatically converted to the hexadecimal ARGB representation (#FFFF0000). Another neat thing about the PropertyGrid used in this manner is that you can see attached properties that could be applied to the object, with the syntax you would expect.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.