In this blog entry, I will discuss what you need to do to successfully interop Winforms with a WPF application and vice versa.
In order to evaluate these 2 different interop methods, 2 demo projects have been created which carry out the functionality shown below:
- .NET Winforms userControl within a .NET3.0/3.5 WPF application
- .NET3.0/3.5 WPF userControl within a .NET Winforms application
A UserControl
was chosen for its ease of development coupled with the fact that the Interop item will always be hosted in a Window of the interop hosts choosing.
As such, the interop test item had to either be a UserControl
or CustomControl
. UserControl
was picked for the reason stated above.
By using these 2 demos project the .NET 2.0 <-> .NET3.0/3.5 Interop is able to be tested for suitability for use on a commercial product.
Just What Is Interop
Interoperability is a property referring to the ability of diverse systems and organizations to work together (inter-operate). The term is often used in a technical systems engineering sense, or alternatively in a broad sense, taking into account social, political, and organizational factors that impact system to system performance.
With respect to software, the term interoperability is used to describe the capability of different programs to exchange data via a common set of exchange formats, to read and write the same file formats, and to use the same protocols.
http://en.wikipedia.org/wiki/Interoperability, up on date 26/02/2008
How to Get a Winform Control Working Within a WPF Application
In order use a Winforms UserControl
/CustomControl
within a WPF application host, the following steps must be taken:
- Reference the WindowsFormsIntegration.dll (should be in the GAC)
- Reference the actual Winforms
UserControl
/CustomControl
projects
- Add the following
using
statement to the code behind for the Window
/Page
that is hosting the Winforms UserControl
/CustomControl
using System.Windows.Forms.Integration;
- Within the
Window
/Page
that is hosting the Winforms UserControl
/CustomControl
, add an xmlns declaration which declares the actual Winforms UserControl
/CustomControl
DLL, an example is as follows:
xmlns:winforms="clr-namespace:WinformsUserControl;
assembly=WinformsUserControl"
- Within the
Window
/Page
that is hosting the Winforms UserControl
/CustomControl
, add a Winforms interop container to host the actual UserControl
/CustomControl
, and also add and name the UserControl
/CustomControl
. An example is as follows:
<!– Winforms User Control –>
<WindowsFormsHost Height="auto" Width="auto">
<winforms:WinformsUserControl x:Name="winformsUserControl"
CustomEvent="WinformsUserControl_CustomEvent" />
</WindowsFormsHost>
I tested out the following features, and this is what the results were:
Feature | Did It Work |
Displayed the same as Winforms version | No |
Property set | Yes |
Property get | Yes |
Method call | Yes |
Custom Event Subscription | Yes |
Custom EventArgs | Yes |
How to Get a WPF Control Working within a Winforms Application
In order use a WPF UserControl
/CustomControl
within a Winforms application host, the following steps must be taken:
- Reference the WindowsFormsIntegration.dll (should be in the GAC)
- Reference the actual WPF
UserControl
/CustomControl
projects
- Add the following
using
statement to the code behind for the Form that is hosting the WPF UserControl
/CustomControl
using System.Windows.Forms.Integration;
- Within the
Window
/Page
that is hosting the WPF UserControl
/CustomControl
, add a WPF interop container to host the actual UserControl
/CustomControl
, and also add and name the UserControl
/CustomControl
, and example is as follows:
private System.Windows.Forms.Integration.ElementHost elhostUserControl11;
private WPFUserControl.WPFUserControl wpfUserControl;
this.elhostUserControl11 = new System.Windows.Forms.Integration.ElementHost();
this.wpfUserControl = new WPFUserControl.WPFUserControl();
....
....
this.elhostUserControl11.Location = new System.Drawing.Point(14, 54);
this.elhostUserControl11.Name = "elhostUserControl11″;
this.elhostUserControl11.Size = new System.Drawing.Size(270, 27);
this.elhostUserControl11.TabIndex = 0;
this.elhostUserControl11.Text = "elementHost1″;
this.elhostUserControl11.Child = this.wpfUserControl;
....
....
this.Controls.Add(this.elhostUserControl11);
I tested out the following features, and this is what the results were:
Feature | Did It Work |
Displayed the same as WPF version | Yes |
Normal Property set | Yes |
Normal Property get | Yes |
Dependency Property set | Yes |
Dependency Property get | Yes |
Method call | Yes |
Pre-Built Routed Event subscription | Yes |
Custom Routed event subscription | Yes |
To illustrate this further, please find attached a small demo solution.