演练:在 WPF 应用程序中承载第三方 Windows 窗体控件
[本文档仅供预览,在以后的发行版中可能会发生更改。包含的空白主题用作占位符。]
本演练演示如何使用 适用于 Visual Studio 的 WPF 设计器 在 WPF 应用程序中承载一个 windows 窗体第三方供应商控件。 有关 windows 窗体和 WPF 互操作性的更多信息,请 迁移和互操作性参见。
在本演练中,您将使用一个 MonthCalendar 控件来表示第三方供应商控件。 您可以创建一个具有 MonthCalendar 控件实例在其 Controls 集合中的 UserControl 类型。 UserControl 类型显示 Date 属性和实现自定义逻辑定义 MonthCalendar 控件行为。 在 WPF 应用程序中, TextBlock 元素绑定到 Date 属性。
在本演练中,您将执行下列任务:
创建 WPF 项目。
创建一个 windows 窗体用户控件封装供应商控件。
在 WPF 应用程序中承载 windows 窗体用户控件。
下图显示应用程序将如何显示。
备注
您看到的对话框和菜单命令可能会与 " 帮助 " 中的描述不同具体取决于您现用的设置或版本。若要更改设置,请选择在 工具 菜单的 导入和导出设置 。有关更多信息,请参见 Visual Studio 设置。
系统必备
您需要以下组件来完成本演练:
- Visual Studio 2012 RC.
创建 WPF 项目
第一步是为宿主应用程序创建 WPF 项目。
创建项目
创建新的 WPF 名为 HostingMonthCalendar的应用程序项目在 Visual Basic 或 Visual C#。 有关更多信息,请参见 如何:创建新的 WPF 应用程序项目。
在 MainWindow.xaml WPF Designer打开。
在 解决方案资源管理器,添加一个对名为 WindowsFormsIntegration.dll 的 WindowsFormsIntegration 程序集,。
创建 windows 窗体组合控件
本过程演示如何通过派生类型创建复合控件从 UserControl 类。
创建 windows 窗体组合控件
在 Visual Basic 中添加个新的 windows 窗体控件库名为 VendorControlLibrary 的项目或 Visual c# 为解决方案。 有关更多信息,请参见 How to: Add and Remove Solution Items。
UserControl1 在 windows 窗体设计器中打开。
在 解决方案资源管理器,右击 UserControl1 文件,然后选择 重命名。
该控件的名称更改为 VendorControl。 当系统询问是否重命名所有引用时,单击 是。
在设计图面上,选择 VendorControl。
在 属性 窗口中,将 Size 属性的值设置为 200,200。
从 工具箱,双击 MonthCalendar 控件。
MonthCalendar 控件随即出现在设计图面上。
在 属性 窗口中,将 MonthCalendar 控件的以下属性。
属性
value
页边距
0,0,0,0
ShowToday
FALSE
将 VendorControl 的大小匹配 MonthCalendar 控件的大小。
选择 MonthCalendar 控件。
在 " 属性 " 窗口中,单击 " 事件 " 选项卡并双击 DateChanged 事件。
在代码编辑器中打开 VendorControl 文件,并且, DateChanged 事件的事件处理程序添加到中。
用下面的代码替换现有代码。 此代码定义一个 Date 属性和一些逻辑限制的 MonthCalendar 控件的日期范围属性, SelectionStart 和 SelectionEnd,该值和 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 } }
在 生成 菜单中,选择 生成解决方案 生成解决方案。
在 WPF 中承载 windows 窗体控件
使用 WindowsFormsHost 元素在 WPF 应用程序中承载 VendorControl。
在 WPF 中承载 windows 窗体控件
在 解决方案资源管理器HostingMonthCalendar 项目中,添加对 VendorControlLibrary 项目。 有关更多信息,请参见 如何:添加或移除引用使用 " 添加引用 " 对话框。
打开在 WPF Designer的 MainWindow.xaml。
从 工具箱,请拖动到设计图面的一个 WindowsFormsHost 控件图面。
对名为 WindowsFormsIntegration.dll 的程序集的引用添加到 HostingMonthCalendar 项目。
在 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>
从 调试 菜单中,选择 启动调试。
单击 MonthCalendar 控件以更改当前日期。 显示所选日期的 WPF TextBlock 元素更新。
后续步骤
如果控件将在 WPF 环境中广泛使用,可以从 WindowsFormsHost 派生您的类并显示 Date 属性。 这使得其他 WPF 控件可以直接绑定到属性, Date ,而无需使用 Path=Child.Date 语法。
还可以在 windows 窗体中承载 WPF 控件。 有关更多信息,请参见 使用 WPF 控件。