Walkthrough: Hosting a Third-Party Windows Forms Control in a WPF Application

[This documentation is for preview only, and is subject to change in later releases. Blank topics are included as placeholders.]

This walkthrough shows you how to use the WPF Designer for Visual Studio to host a Windows Forms third-party vendor control in a WPF application. For more information about Windows Forms and WPF interoperability, see Migration and Interoperability.

In this walkthrough, you will use a MonthCalendar control to represent a third-party vendor control. You create a UserControl type which has an instance of the MonthCalendar control in its Controls collection. The UserControl type exposes a Date property and implements custom logic to define the MonthCalendar control's behavior. In the WPF application, a TextBlock element is bound to the Date property.

In this walkthrough, you perform the following tasks:

  • Create the WPF project.

  • Create a Windows Forms user control to encapsulate the vendor control.

  • Host the Windows Forms user control in a WPF application.

The following illustration shows how your application will appear.

Hosted Windows Forms Control
Note Note

The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings or edition. To change your settings, choose Import and Export Settings on the Tools menu. For more information, see Visual Studio Settings.

You need the following components to complete this walkthrough:

  • Visual Studio 2012 RC.

The first step is to create the WPF project for the host application.

To create the project

  1. Create a new WPF Application project in Visual Basic or Visual C# named HostingMonthCalendar. For more information, see How to: Create a New WPF Application Project.

    MainWindow.xaml opens in the WPF Designer.

  2. In Solution Explorer, add a reference to the WindowsFormsIntegration assembly, which is named WindowsFormsIntegration.dll.

This procedure shows how to create a composite control by deriving a type from the UserControl class.

To create the Windows Forms composite control

  1. Add a new Windows Forms Control Library project in Visual Basic or Visual C# named VendorControlLibrary to the solution. For more information, see How to: Add and Remove Solution Items.

    UserControl1 opens in the Windows Forms Designer

  2. In Solution Explorer, right-click the UserControl1 file, and select Rename.

  3. Change the name of the control to VendorControl. When you are asked if you want to rename all references, click Yes.

  4. On the design surface, select the VendorControl.

  5. In the Properties window, set the value of the Size property to 200,200.

  6. From the Toolbox, double-click the MonthCalendar control.

    A MonthCalendar control appears on the design surface.

  7. In the Properties window, set the following properties for the MonthCalendar control.

    Property

    Value

    Margin

    0,0,0,0

    ShowToday

    False

  8. Set the size of VendorControl to match the size of the MonthCalendar control.

  9. Select the MonthCalendar control.

  10. In the Properties window, click the Events tab and double-click the DateChanged event.

    The VendorControl file opens in the Code Editor, and an event handler for the DateChanged event is added.

  11. Replace the existing code with the following code. This code defines a Date property and some logic for restricting the MonthCalendar control's date range properties, SelectionStart and SelectionEnd, to the same value as TodayDate. This code also implements the INotifyPropertyChanged interface, which is used in WPF data binding.

    
                      
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace VendorControlLibrary
    {
        public partial class VendorControl : UserControl, INotifyPropertyChanged
        {
            public VendorControl()
            {
                InitializeComponent();
            }
    
            [Browsable(true)]
            public string Date
            {
                get
                {
                    return this.monthCalendar1.TodayDate.ToShortDateString();
                }
    
                set
                {
                    if (value != this.monthCalendar1.TodayDate.ToShortDateString())
                    {
                        DateTime newDate = DateTime.Parse(value);
                        this.SetDate(newDate);
                        this.OnPropertyChanged("Date");
                    }
                }
            }
    
            private void monthCalendar1_DateChanged(object sender, DateRangeEventArgs e)
            {
                this.SetDate(e.Start);
                this.OnPropertyChanged("Date");
            }
    
            private void SetDate(DateTime date)
            {
                this.monthCalendar1.TodayDate = date;
                this.monthCalendar1.SelectionStart = date;
                this.monthCalendar1.SelectionEnd = date;
            }
    
            #region INotifyPropertyChanged Implementation
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
            #endregion
        }
    }
    
    
                    
    
  12. On the Build menu, select Build Solution to build the solution.

You use the WindowsFormsHost element to host VendorControl in a WPF application.

To host the Windows Forms control in WPF

  1. In the HostingMonthCalendar project of Solution Explorer, add a reference to the VendorControlLibrary project. For more information, see How to: Add or Remove References By Using the Add Reference Dialog Box.

  2. Open MainWindow.xaml in the WPF Designer.

  3. From the Toolbox, drag a WindowsFormsHost control onto the design surface.

    A reference to the assembly named WindowsFormsIntegration.dll is added to the HostingMonthCalendar project.

  4. In XAML view, replace the existing markup with the following markup. This XAML maps the VendorControlLibrary namespace and binds a TextBlock element to the Date property on VendorControl.

    
    <Window x:Class="HostingMonthCalendar.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:v="clr-namespace:VendorControlLibrary;assembly=VendorControlLibrary"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
    
            <WindowsFormsHost Name="Host" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
                <v:VendorControl Date="2/2/03" />
            </WindowsFormsHost>
    
            <TextBlock Grid.Row="1" 
                       Text="{Binding ElementName=Host, Path=Child.Date, Mode=OneWay, UpdateSourceTrigger=PropertyChanged }" 
                       HorizontalAlignment="Stretch" 
                       VerticalAlignment="Center" 
                       TextAlignment="Center" 
                       TextDecorations="None" 
                       FontSize="24" />
        </Grid>
    </Window>
    
    
    
  5. From the Debug menu, select Start Debugging.

  6. Click the MonthCalendar control to change the current date. The WPF TextBlock element updates to display the selected date.

  • If your control will be widely used in a WPF environment, you can derive your own class from WindowsFormsHost and expose the Date property. This enables other WPF controls to bind directly to the Date property, without using the Path=Child.Date syntax.

  • You can also host WPF controls in Windows Forms. For more information, see Using WPF Controls.

Show: