A little while back, we did a tutorial on how to embed WinFoms controls
inside of WPF application (you can read all about it
here).
Today, we are going to flip that on its head - we are going to take a
look at how to embed WPF controls inside of a WinForms application.
You might be thinking to yourself "why would someone want to do that?" A
great question, and there are a couple different reasons. First, perhaps
you have an application already written in WinForms, but you want to
move to WPF. Instead of rewriting the entire thing from scratch (which
might be a large amount of work, and might be time/cost prohibitive),
you can rewrite portions of the application as time allows or when you
need to redo a particular section anyway.
Another reason would be if there is a area of your app that would be
easy to do in WPF (maybe because of the animation features, or the
composibility) while in WinForms it would be difficult.
So what do we need to do to enable this integration? Well, first off, we
need to add a reference to the Visual Studio project. You do this by
right clicking on "References" in the Solution Explorer and choosing
"Add Reference":
Once you have the dialog up, you want to scroll to the bottom on the
.NET tab and choose the "WindowsFormsIntegration" component, and hit OK:
At this point, you probably want to create the WPF user control that you
want to add to your app. If its already written, you can add it through
the Add Existing Item menu option, and if you need to write one, you can
choose "Add New Item" and under WPF choose "User Control". In my case I
want to create a new one, and I'm going to name it "MyWPFControl":
So my made-up reason why I want a WPF control in my WinForms app is that
I want a custom combo box - or really a combo box with some custom
items. While this is doable in WinForms, it is hard. Downright annoying
in many ways. In WPF, though, its really easy, since you can put
whatever you want in a
ComboBoxItem
. In this case, my user control
consists of a combo box with three items - a circle, a triangle, and a
rectangle:<UserControl x:Class="WPFInWinForms.MyWPFControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<ComboBox>
<ComboBoxItem Margin="2">
<Ellipse Width="20" Height="20" Stroke="Black" />
</ComboBoxItem>
<ComboBoxItem Margin="2">
<Path Stroke="Black" Data="M 0,0 L 20,0 L 10,20 Z" />
</ComboBoxItem>
<ComboBoxItem Margin="2">
<Rectangle Stroke="Black" Width="20" Height="20" />
</ComboBoxItem>
</ComboBox>
</Grid>
</UserControl>
OK, now that we have the control we want to add, how do we add it? Well,
there are two ways of going about this - one is through the designer,
and the other is by adding the control manually in code. We are fist
going to take a look at the designer way of doing things.
When we added that reference earlier, one of the things it did was give
us access to a control called
ElementHost
. This control is for WPF in
WinForms what the WindowsFormsHost
was for WinForms in WPF. In the
designer, you can find this control in the Toolbox underneath "WPF
Interoperability":
So once you drag an
ElementHost
onto your form, the designer makes
things really easy for you. You just click on the little arrow on the
upper right of the ElementHost
and you get a couple options. The one
we care about is the combobox for "Select Hosted Content". When you
click this, you get to choose what WPF control you want to host in the
ElementHost
:
Once you do that, well, thats it. You can run the app, and the WPF
control will show up exactly where you put it:
Doing all of this in code is also quite easy. In fact, I'll just throw
all the code up here in one block:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
namespace WPFInWinForms
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ElementHost elhost = new ElementHost();
elhost.Size = new Size(110, 60);
elhost.Location = new Point(45,35);
MyWPFControl wpfctl = new MyWPFControl();
elhost.Child = wpfctl;
this.Controls.Add(elhost);
}
}
}
So the first thing needed is that last using statement. The
ElementHost
lives in that namespace, so we add a using statement for
it. After that, we just create a new ElementHost
, and set its normal
WinForms properties. Then we create an instance of the wpf control we
want, and add that as the child for the ElementHost
. Finally, we add
the ElementHost
as a child to the current form - and we are all done!
So that is it for using WPF controls inside of Windows Forms. You can
download the little sample app from
here if you
would like to play with the code yourself.
Source Files:
Comments
Post a Comment