Click here to Skip to main content
15,881,687 members
Articles / Desktop Programming / WPF

How to Easily Host WPF Control inside Windows Form Application

Rate me:
Please Sign up or sign in to vote.
4.93/5 (29 votes)
31 Mar 2014CPOL3 min read 119K   5K   74   15
This article demonstrates an easy way to host WPF control inside Windows Form application.

Introduction

In this article, I will demonstrate how to create a "grid like" combo-box and host it inside a Windows Form application.

Image 1

Background

WinForms applications have limited user interface (UI) abilities compared with WPF. Does this justify transposing the whole application from WinForms to WPF?

In my opinion, not always. Sometimes you can easily give a “facelift” to your application using WPF controls.

As a side note, if you want to upgrade your Windows Form application, you should consider HTML5 and not WPF. While I personally love working with WPF, upgrading to HTML5 will get you a multi-platform web application at a lower cost, especially if you do it automatically using transposition tools. I've done many of these projects and it is certainly easier than re-writing it to WPF.

However, in the meantime, you can use “hosting” - embedding a WPF control inside your Windows Form application in order to take advantage of the richness (and easiness - after some practice) of WPF within a Windows Form application. Also, creating complicated controls in WPF usually takes less time than creating them in Windows Form.

MSDN has an article about "Hosting a WPF composite control in Windows Forms" but I believe it to be too complicated.

What I present here is an easy example of hosting a WPF control inside Windows Forms application in a way that is simple to follow and implement, and is also more suitable from the perspective of project architecture.

Stages

  1. Creating the WPF "Grid like" combo-box
  2. Creating the Windows form hosting Control
  3. Adding the control to Windows Form application

1. Creating WPF "Grid like" Combo-box

Let us start by writing the WPF control.

Our aim is a simple control of a combo-box containing "grid-like" properties of a “customer”:

XAML

HTML
<UserControl x:Class="WindowsFormsControlLibrary1.ComboBoxWithGrid"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="50" d:DesignWidth="250">
    <Grid>
        <ComboBox x:Name="comboBox"
        Margin="4"
        ItemsSource="{Binding Customers}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Label BorderThickness="1,1,0,1" 
                        BorderBrush="Black" Content="{Binding Path=Name}" />
                        <Label BorderThickness="1,1,0,1" 
                        BorderBrush="Black" Content="{Binding Path=Address}" />
                        <Label BorderThickness="1" 
                        BorderBrush="Black" Content="{Binding Path=TelephoneNumber}" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </Grid>
</UserControl>  

As we can see in the XAML above, we define a combo-box with customer as an item source. The combo-box has an item template for presenting the customer details in a "grid-like" style:

Image 2

In WPF, it is easily done using three labels and binding their context into the "Customer" class properties.

Customer Class

C#
public class Customer
{
    public string Name { get; set; }

    public string Address { get; set; }

    public string TelephoneNumber { get; set; }
}

Then, all we have left to do is to write the WPF control code behind:

C#
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class ComboBoxWithGrid : UserControl
{
    public ComboBoxWithGrid()
    {
        InitializeComponent();
        SelectedIndex = 0;

        this.DataContext = this;
    }

    public int SelectedIndex
    {
        get
        {
           return comboBox.SelectedIndex;
        }
        set
        {
            comboBox.SelectedIndex = value;
        }
    }
    public List<Customer> Customers { get; set; }
}

As we can see, the code behind is very simple, setting the DataContext as this, exposing the Customers list, for outside & for the XAML data binding, and also exposing the select index for outside only.

2. Creating the Windows Form Hosting Control

This step is actually easier. I am creating a simple class that inherits from System.Windows.Forms.Integration.ElementHost:

C#
[Designer("System.Windows.Forms.Design.ControlDesigner, System.Design")]
[DesignerSerializer("System.ComponentModel.Design.Serialization.TypeCodeDomSerializer , System.Design", "System.ComponentModel.Design.Serialization.CodeDomSerializer, System.Design")]
public class ComboBoxWithGrid_WinformsHost : System.Windows.Forms.Integration.ElementHost
{
    protected ComboBoxWithGrid m_WPFComboBoxWithGrid = new ComboBoxWithGrid();

    public ComboBoxWithGrid_WinformsHost()
    {
        base.Child = m_WPFComboBoxWithGrid;
    }

    public int SelectedIndex
    {
        get
        {
            return m_WPFComboBoxWithGrid.SelectedIndex;
        }
        set
        {
            m_WPFComboBoxWithGrid.SelectedIndex = value;
        }
    }

    public List<Customer> Customers
    {
        get
        {
            return m_WPFComboBoxWithGrid.Customers;
        }
        set
        {
            m_WPFComboBoxWithGrid.Customers = value;
        }
    }
}

This class inherits from ElementHost object that holds the WPF control as a child.

Please notice that I have override back to default the Designer Smart-Tag and the DesignerSerializer attributes in order to prevent an override of the Child element by the Designer.

3. Adding the Control to Windows Form Application

First, we just need to drag & drop the new control inside our Windows Form:

Image 3

And then, connect the customer list to the control by code-behind:

C#
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        var customers = new List<Customer>();

        for (int i = 0; i < 10; i++)
        {
            customers.Add(new Customer() { Name = "Name" + i,
            Address = "Address" + i, TelephoneNumber = "TelephoneNumber" + i });
        }

        this.comboBoxWithGrid_WinformsHost1.Customers = customers;

        this.comboBoxWithGrid_WinformsHost1.SelectedIndex = 6;
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer GalilCS
Israel Israel
My name is Shai Vashdi and I’m the CTO & Co-Founder of GalilCS.
GalilCS provides industrialized, low-cost IT services (ILCS) to corporations around the globe. We specialize in code modernization projects (VB6 to C# WinForms/HTML5, for example) and code refactoring projects.
Most of my work revolves around the management of these projects and the creation of new tools for refactoring code. As a bonus, I also get to lecture about Microsoft programming languages.
For more information, visit GalilCS.

Comments and Discussions

 
NewsIs there a way to use standard wpf control on WinForm? Pin
Member 101955059-Mar-20 2:44
professionalMember 101955059-Mar-20 2:44 
QuestionHow Can I add Data from a method other than Constructor? Pin
jfshimul5-Apr-17 22:50
professionaljfshimul5-Apr-17 22:50 
QuestionWorked Successfully Pin
Asad CR9-Mar-17 2:46
Asad CR9-Mar-17 2:46 
QuestionEdit new interface... Pin
Menci Lucio28-Mar-14 0:19
professionalMenci Lucio28-Mar-14 0:19 
AnswerRe: Edit new interface... Pin
Shai Vashdi29-Mar-14 11:02
Shai Vashdi29-Mar-14 11:02 
GeneralRe: Edit new interface... Pin
Menci Lucio30-Mar-14 22:37
professionalMenci Lucio30-Mar-14 22:37 
GeneralRe: Edit new interface... Pin
Shai Vashdi30-Mar-14 23:44
Shai Vashdi30-Mar-14 23:44 
GeneralRe: Edit new interface... Pin
Shai Vashdi31-Mar-14 3:36
Shai Vashdi31-Mar-14 3:36 
GeneralRe: Edit new interface... Pin
Menci Lucio1-Apr-14 7:16
professionalMenci Lucio1-Apr-14 7:16 
GeneralRe: Edit new interface... Pin
Shai Vashdi2-Apr-14 1:42
Shai Vashdi2-Apr-14 1:42 
GeneralRe: Edit new interface... Pin
Menci Lucio2-Apr-14 22:00
professionalMenci Lucio2-Apr-14 22:00 
GeneralRe: Edit new interface... Pin
Shai Vashdi2-Apr-14 22:46
Shai Vashdi2-Apr-14 22:46 
GeneralRe: Edit new interface... Pin
Philippe Mori17-Feb-15 12:17
Philippe Mori17-Feb-15 12:17 
QuestionRoot element is missing. Pin
RAND 45586622-Mar-14 6:44
RAND 45586622-Mar-14 6:44 
AnswerRe: Root element is missing. Pin
Shai Vashdi23-Mar-14 4:28
Shai Vashdi23-Mar-14 4:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.