Click here to Skip to main content
11,632,260 members (71,374 online)
Click here to Skip to main content

How to Easily Host WPF Control inside Windows Form Application

, 31 Mar 2014 CPOL 31.6K 1.5K 62
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.

You may also be interested in...

Comments and Discussions

 
QuestionEdit new interface... Pin
Member 1063000828-Mar-14 0:19
memberMember 1063000828-Mar-14 0:19 
AnswerRe: Edit new interface... Pin
Shai Vashdi29-Mar-14 11:02
memberShai Vashdi29-Mar-14 11:02 
GeneralRe: Edit new interface... Pin
Member 1063000830-Mar-14 22:37
memberMember 1063000830-Mar-14 22:37 
GeneralRe: Edit new interface... Pin
Shai Vashdi30-Mar-14 23:44
memberShai Vashdi30-Mar-14 23:44 
GeneralRe: Edit new interface... Pin
Shai Vashdi31-Mar-14 3:36
memberShai Vashdi31-Mar-14 3:36 
GeneralRe: Edit new interface... Pin
Member 106300081-Apr-14 7:16
memberMember 106300081-Apr-14 7:16 
GeneralRe: Edit new interface... Pin
Shai Vashdi2-Apr-14 1:42
memberShai Vashdi2-Apr-14 1:42 
GeneralRe: Edit new interface... Pin
Member 106300082-Apr-14 22:00
memberMember 106300082-Apr-14 22:00 
GeneralRe: Edit new interface... Pin
Shai Vashdi2-Apr-14 22:46
memberShai Vashdi2-Apr-14 22:46 
GeneralRe: Edit new interface... Pin
Philippe Mori17-Feb-15 12:17
memberPhilippe Mori17-Feb-15 12:17 
QuestionRoot element is missing. Pin
Member 45586622-Mar-14 6:44
memberMember 45586622-Mar-14 6:44 
AnswerRe: Root element is missing. Pin
Shai Vashdi23-Mar-14 4:28
memberShai 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 | Terms of Use | Mobile
Web02 | 2.8.150728.1 | Last Updated 31 Mar 2014
Article Copyright 2014 by Shai Vashdi
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid