Click here to Skip to main content
Click here to Skip to main content
Go to top

How to Easily Host WPF Control inside Windows Form Application

, 31 Mar 2014
Rate this:
Please Sign up or sign in to vote.
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.

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

<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:

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

Customer Class

    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:

    /// <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:

    [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:

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

    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)

Share

About the Author

Shai Vashdi
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.
Follow on   Twitter   LinkedIn

Comments and Discussions

 
QuestionEdit new interface... PinmemberMember 1063000828-Mar-14 0:19 
AnswerRe: Edit new interface... PinmemberShai Vashdi29-Mar-14 11:02 
GeneralRe: Edit new interface... PinmemberMember 1063000830-Mar-14 22:37 
GeneralRe: Edit new interface... PinmemberShai Vashdi30-Mar-14 23:44 
GeneralRe: Edit new interface... PinmemberShai Vashdi31-Mar-14 3:36 
GeneralRe: Edit new interface... PinmemberMember 106300081-Apr-14 7:16 
GeneralRe: Edit new interface... PinmemberShai Vashdi2-Apr-14 1:42 
GeneralRe: Edit new interface... PinmemberMember 106300082-Apr-14 22:00 
GeneralRe: Edit new interface... PinmemberShai Vashdi2-Apr-14 22:46 
QuestionRoot element is missing. PinmemberMember 45586622-Mar-14 6:44 
AnswerRe: Root element is missing. PinmemberShai Vashdi23-Mar-14 4:28 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140926.1 | Last Updated 31 Mar 2014
Article Copyright 2014 by Shai Vashdi
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid