演练:在 WPF 应用程序中承载第三方 Windows 窗体控件

更新:2010 年 9 月

本演练向您演示如何使用 适用于 Visual Studio 的 WPF 设计器在 WPF 应用程序中承载 Windows 窗体第三方供应商控件。 有关 Windows 窗体和 WPF 互操作性的更多信息,请参见迁移和互操作性

在本演练中,将使用一个 MonthCalendar 控件来表示第三方供应商控件。 您创建一个 UserControl 类型,该类型在其 Controls 集合中具有 MonthCalendar 控件的实例。 UserControl 类型公开 Date 属性并实现自定义逻辑,以定义 MonthCalendar 控件的行为。 在 WPF 应用程序中,TextBlock 元素绑定到 Date 属性。

在本演练中,您将执行下列任务:

  • 创建 WPF 项目。

  • 创建一个用于封装供应商控件的 Windows 窗体用户控件。

  • 在 WPF 应用程序中承载该 Windows 窗体用户控件。

下面的插图说明您的应用程序将如何显示。

寄宿的 Windows 窗体控件

提示

显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您现用的设置或版本。 若要更改设置,请在“工具”菜单上选择“导入和导出设置”。 有关更多信息,请参见 使用设置

系统必备

您需要以下组件来完成本演练:

  • Visual Studio 2010.

创建 WPF 项目

第一步是为宿主应用程序创建 WPF 项目。

创建项目

  1. 使用 Visual Basic 或 Visual C# 创建一个名为 HostingMonthCalendar 的新 WPF 应用程序项目。 有关更多信息,请参见如何:创建新的 WPF 应用程序项目

    MainWindow.xaml 将在 WPF 设计器中打开。

  2. 在**“解决方案资源管理器”**中,添加一个对名为 WindowsFormsIntegration.dll 的 WindowsFormsIntegration 程序集的引用。

创建 Windows 窗体组合控件

本过程演示如何通过从 UserControl 类派生类型来创建组合控件。

创建 Windows 窗体组合控件

  1. 使用 Visual Basic 或 Visual C# 为解决方案添加一个名为 VendorControlLibrary 的新 Windows 窗体控件库项目。 有关更多信息,请参见如何:添加和移除解决方案项

    UserControl1 在 Windows 窗体设计器中打开。

  2. 在**“解决方案资源管理器”中右击 UserControl1 文件,然后选择“重命名”**。

  3. 将该控件的名称更改为 VendorControl。 当系统询问是否重命名所有引用时,请单击**“是”**。

  4. 在设计图面上选择 VendorControl。

  5. 在**“属性”**窗口中,将 Size 属性的值设置为 200,200。

  6. 在**“工具箱”**中双击 MonthCalendar 控件。

    一个 MonthCalendar 控件随即出现在设计图面上。

  7. 在**“属性”**窗口中,设置 MonthCalendar 控件的下列属性。

    Property

    Margin

    0,0,0,0

    ShowToday

    False

  8. 将 VendorControl 的大小设置为与 MonthCalendar 控件的大小相匹配。

  9. 选择 MonthCalendar 控件。

  10. 在“属性”窗口中,单击“事件”选项卡并双击**“DateChanged”**事件。

    将在代码编辑器中打开 VendorControl 文件,并添加**“DateChanged”**事件的事件处理程序。

  11. 用下面的代码替换现有代码。 此代码定义一个 Date 属性,并将用于限制 MonthCalendar 控件日期范围属性 SelectionStartSelectionEnd 的一些逻辑定义为与 TodayDate 的值相同。 此代码还实现 INotifyPropertyChanged 接口,该接口用在 WPF 数据绑定中。

    Imports System
    Imports System.Collections.Generic
    Imports System.ComponentModel
    Imports System.Drawing
    Imports System.Data
    Imports System.Linq
    Imports System.Text
    Imports System.Windows.Forms
    
    Public Class VendorControl
        Inherits UserControl
        Implements INotifyPropertyChanged
    
        <Browsable(True)> _
        Public Property [Date]() As String
            Get
                Return Me.MonthCalendar1.TodayDate.ToShortDateString()
            End Get
    
            Set(ByVal value As String)
                If value <> Me.MonthCalendar1.TodayDate.ToShortDateString() Then
                    Dim newDate As DateTime = DateTime.Parse(value)
                    Me.SetDate(newDate)
                    Me.NotifyPropertyChanged("Date")
                End If
            End Set
        End Property
    
    
        Private Sub monthCalendar1_DateChanged( _
            ByVal sender As Object, ByVal e As DateRangeEventArgs) _
        Handles MonthCalendar1.DateChanged
            Me.SetDate(e.Start)
            Me.NotifyPropertyChanged("Date")
    
        End Sub
    
    
        Private Sub SetDate(ByVal [date] As DateTime)
            Me.MonthCalendar1.TodayDate = [date]
            Me.MonthCalendar1.SelectionStart = [date]
            Me.MonthCalendar1.SelectionEnd = [date]
    
        End Sub
    
    #Region "INotifyPropertyChanged Implementation"
    
        Public Event PropertyChanged As PropertyChangedEventHandler _
            Implements INotifyPropertyChanged.PropertyChanged
    
        Private Sub NotifyPropertyChanged(ByVal info As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
        End Sub
    
    #End Region
    End Class
    
    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. 在**“生成”菜单上选择“生成解决方案”**以生成解决方案。

在 WPF 中承载 Windows 窗体控件

可以使用 WindowsFormsHost 元素在 WPF 应用程序中承载 VendorControl。

在 WPF 中承载 Windows 窗体控件

  1. 在**“解决方案资源管理器”**的 HostingMonthCalendar 项目中,添加对 VendorControlLibrary 项目的引用。 有关更多信息,请参见如何:在 Visual Studio 中添加或移除引用

  2. 在 WPF 设计器中打开 MainWindow.xaml。

  3. WindowsFormsHost 控件从**“工具箱”**中拖动到设计图面。

    将在 HostingMonthCalendar 项目中添加一个对名为 WindowsFormsIntegration.dll 的程序集的引用。

  4. 在 XAML 视图中,将现有标记替换为以下标记。 此 XAML 映射 VendorControlLibrary 命名空间,并将 TextBlock 元素绑定到 VendorControl 上的 Date 属性。

    <Window x:Class="HostingMonthCalendar.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://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. 从**“调试”菜单中选择“启动调试”**。

  6. 单击 MonthCalendar 控件以更改当前日期。 WPF TextBlock 元素更新,以显示所选日期。

后续步骤

  • 如果控件将在 WPF 环境中广泛使用,则可从 WindowsFormsHost 中派生自己的类并公开 Date 属性。 这使得其他 WPF 控件可以直接绑定到 Date 属性,而不使用 Path=Child.Date 语法。

  • 还可以在 Windows 窗体中承载 WPF 控件。 有关更多信息,请参见使用 WPF 控件

请参见

任务

演练:在 WPF 中承载 Windows 窗体控件

参考

WindowsFormsHost

ElementHost

其他资源

使用 WPF 设计器中的控件

迁移和互操作性

修订记录

日期

修订记录

原因

2010 年 9 月

添加了丢失的步骤。

客户反馈