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:
thankx for such a simple to follow tutorial.
I have one question, how should we use the WPF user control which is created in control library? The control library will have multiple xaml file, do we have to add all those manually? can we just add reference to control library DLL and add it under element host?
Yup, you should be able to just add a reference to the dll and you'll have access to any of the controls in that dll.
Can I embed a wpf control in a dotnet 2.0 winform ?
... how would embed manually just using the sdk?
Did you succeed in doing this?
i've coded my project in vb .net 2005(windows application)... Now i'ld like to do the same project in vb .net 2008(wpf application) along with expression blend... i'm new to *.xaml.vb files... properties and codes of *.vb differs from *.xaml.vb... (like me.hide and me.show are missing in *.xaml.vb and msgbox() is replaced by messagebox.show())... so, can u pls list me out *.xaml.vb codes or guide me for the same... thanks in advance
your tutorial is very nice. It's completely step by step tutorial that helps beginners.......
What if I want to add text in each combo box items i.e. in first item u have added ellipse - I want text beside it as "Ellipse".... how this is possible ?
You could add a stack panel in the Combobox item and add elements in the stack panel.
Now how do I make it interact with methods in the containing form? ie. call MySimpleMethod()
public void MySimpleMethod() { MessageBox.Show("hello world"); }
You could do this two ways:
Add a property to the WPF control that holds the parent form. Then the WPF control can just call public methods like it would on any other object.
Another way is to have events in the WPF control that are attached in the parent form. Then, the WPF control can just raise the events and the form can handle them however it wants. This is probably the better solution, as it makes the control more portable.
Hi,
I have a Windows Form with a Combo box & OK button in Panel1. When a user chooses a particular value from the drop down in the Combo box, and clicks OK, in the Panel2, I would display some charts using WPF user control. But how do I access the value of the Combo box in my WPF User control? I.e., how do I check what the user chose, in my WPF Application?
Please help,
take care
I just wanted to say "Thank you". I have tried before to just get a WPF control on a windows form as we already have an app that we spent loads of time building, but wanted to use the WPF grid. Anyway after following a different tutorial, I gave up. Tried it again today with your tutorial and it worked GREAT! Your site is now bookmarked :)
Link From window form to WPF
hi,
i develop system using VB express Edition 2008, i want put WPF application in my application, so is it possible i want to link WinForm to WPF or WPF to WinForm ?
if it is possible , may i know how it works? somebody help me...
its simple and superb
Thank you for your nice tutorial:)
I have a problem, when I want to select hosted content for ElementHost, there is nothing for selecting. the MyWPFControl doesn't add to here. But previously I’ve added MyWPFControl.xaml to my project. What do you think? in which step I made mistake?
You have to recompile the code if it hasn't already been compiled, then it should show up.
good one..
Hi,
My basic requirement is to develop an WPF application in which i want to use Windows form as a athentication page (to give anthtication for user).So..., to do this:- i have created a WPF application.then i added Windows form by using "add new item".I called (in windows1.xaml.cs) the "windows from" from WPF as following.
public
partial class Window1 :
{
public Window1() {
Form1 frm1 = new Form1(); //added by me frm1.Show(); //added by me
System.Windows.Threading.
Dispatcher.Run(); //added by me InitializeComponent();
}
}.
?By adding the above steps (//added by me), i'm able to call windows form while running the application.Upto this fine.
?Now, i kept a botton on my "windows from".And on botton click i want to invoke the WPF window (that is "windows1").How should i do this??
?Pls help.
Wonderful article. Much appriciated.
Wow. This works and is cool.
I have created one usercontrol and how can i add that user control to a wpf form......please replay......
in relation to current article Skill WPF Tutorial - Using WPF In WinForms
how do i use Wpf control that is located in a different dll?
06/12/2012 - 00:36 in relation to current article Skill WPF Tutorial - Using WPF In WinForms
how do i use Wpf control that is located in a different dll? i means that i have alredy tried to add a reference to the wpfContril dll but it isn't shown in the element host. if anyone can send a full example demonstarting this case?
i have noticed that when i generate the WpfControl in the other dll it is generated without the initializeComponet content. hence it can't be shown on the traget form. as as consequence to that i generated the control in the winforms project and then i copied it to the dll and now thanks g-d all is ready.
I've implemented the code above with exception of constructor taking an integer as a parameter. First time it runs ok, but when I call the constructor again, nothing happens. Any reason why it's like that?
which class is used to invoke the winform application??