演练:在 Windows Presentation Foundation 中承载 Windows 窗体复合控件
更新:2007 年 11 月
Windows Presentation Foundation (WPF) 提供用于创建应用程序的丰富环境。但是,如果您对 Windows 窗体代码的投入较大,那么更有效的办法是在您的 WPF 应用程序中至少重用该代码的一部分,而不是从头开始重新编写应用程序。最常见的情况是您有现有的自定义 Windows 窗体控件。在某些情况下,您可能甚至没有对这些控件的源代码的访问权。WPF 提供了一个在 WPF 应用程序中承载此类控件的简单过程。例如,您可以在承载专用的 System.Windows.Forms.DataGridView 控件时,将 WPF 用于大多数编程。
本演练引导您创建一个在 WPF 页上承载一个复合 Windows 窗体控件的应用程序。该一般过程可以扩展到更复杂的应用程序和控件。
本演练分为两部分。第一部分简要介绍 Windows 窗体控件的实现。第二部分详细讨论如何在 WPF 应用程序中承载该控件、从该控件接收事件以及访问该控件的一些属性。
本演练涉及以下任务:
实现 Windows 窗体控件。
使用 Windows Presentation Foundation 实现宿主应用程序。
有关本演练中所演示的任务的完整代码清单,请参见在 Windows Presentation Foundation 中承载 Windows 窗体复合控件的示例。
先决条件
您需要以下组件来完成本演练:
- Visual Studio 2008.
实现 Windows 窗体控件
本示例中使用的 Windows 窗体控件是一个简单的数据输入窗体。该窗体接受用户的名称和地址,然后使用自定义事件将此信息返回到宿主。下图演示呈现的控件。
Windows 窗体控件
创建项目
若要开始创建项目,请执行以下操作:
启动 Microsoft Visual Studio,打开“新建项目”对话框。
选择“C# 项目”和“Windows 窗体控件库”模板。
将新项目命名为 MyControls,并单击“确定”以创建此项目。默认项目包含一个名为 UserControl1 的控件。
将 UserControl1 的名称更改为 MyControl1。
您的项目应当具有对以下系统 DLL 的引用。如果默认情况下未包括其中任何一个 DLL,请将它添加到项目中。
System
System.Data
System.Drawing
System.Windows.Forms
System.XML
向窗体添加控件
向窗体添加控件:
- 打开 MyControl1 的设计器。
在窗体中放置六个 System.Windows.Forms.Label 控件及其相应的 System.Windows.Forms.TextBox 控件,大小和排列方式如前面的插图中所示。在此示例中,TextBox 控件命名为:
txtName
txtAddress
txtCity
txtState
txtZip
添加两个标有“OK”(确定)和“Cancel”(取消)的 System.Windows.Forms.Button 控件。在此示例中,按钮名称分别为 btnOK 和 btnCancel。
实现支持代码
打开窗体的代码视图。控件通过引发自定义 OnButtonClick 事件向其宿主返回所收集的数据。这些数据包含在事件参数对象中。下面的代码示例演示事件和委托声明。将此代码添加到代码文件中由设计器生成的代码之下。
Public Delegate Sub MyControlEventHandler(ByVal sender As Object, ByVal args As MyControlEventArgs)
Public Event OnButtonClick As MyControlEventHandler
public delegate void MyControlEventHandler(object sender, MyControlEventArgs args);
public event MyControlEventHandler OnButtonClick;
MyControlEventArgs 类包含要返回到宿主的信息。向窗体的命名空间添加以下类。
Public Class MyControlEventArgs
Inherits EventArgs
Private _Name As String
Private _StreetAddress As String
Private _City As String
Private _State As String
Private _Zip As String
Private _IsOK As Boolean
Public Sub New(ByVal result As Boolean, ByVal name As String, ByVal address As String, ByVal city As String, ByVal state As String, ByVal zip As String)
_IsOK = result
_Name = name
_StreetAddress = address
_City = city
_State = state
_Zip = zip
End Sub
Public Property MyName() As String
Get
Return _Name
End Get
Set
_Name = value
End Set
End Property
Public Property MyStreetAddress() As String
Get
Return _StreetAddress
End Get
Set
_StreetAddress = value
End Set
End Property
Public Property MyCity() As String
Get
Return _City
End Get
Set
_City = value
End Set
End Property
Public Property MyState() As String
Get
Return _State
End Get
Set
_State = value
End Set
End Property
Public Property MyZip() As String
Get
Return _Zip
End Get
Set
_Zip = value
End Set
End Property
Public Property IsOK() As Boolean
Get
Return _IsOK
End Get
Set
_IsOK = value
End Set
End Property
End Class
public class MyControlEventArgs : EventArgs
{
private string _Name;
private string _StreetAddress;
private string _City;
private string _State;
private string _Zip;
private bool _IsOK;
public MyControlEventArgs(bool result,
string name,
string address,
string city,
string state,
string zip)
{
_IsOK = result;
_Name = name;
_StreetAddress = address;
_City = city;
_State = state;
_Zip = zip;
}
public string MyName
{
get { return _Name; }
set { _Name = value; }
}
public string MyStreetAddress
{
get { return _StreetAddress; }
set { _StreetAddress = value; }
}
public string MyCity
{
get { return _City; }
set { _City = value; }
}
public string MyState
{
get { return _State; }
set { _State = value; }
}
public string MyZip
{
get { return _Zip; }
set { _Zip = value; }
}
public bool IsOK
{
get { return _IsOK; }
set { _IsOK = value; }
}
}
用户单击“OK”(确定)或“Cancel”(取消)按钮时,Control.Click 事件处理程序创建一个 MyControlEventArgs 对象,该对象包含这些数据并引发 OnButtonClick 事件。两个处理程序的唯一区别在于事件参数的 IsOK 属性。通过该属性,宿主可以确定单击了哪个按钮。对于“OK”(确定)按钮,它设置为 true,对于“Cancel”(取消)按钮,则设置为 false。下面的代码示例演示两个按钮处理程序。将此代码添加到您的类中,放在本节第一个代码示例中演示的事件和委托声明之下。
Private Sub OKButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click
Dim retvals As New MyControlEventArgs(True, txtName.Text, txtAddress.Text, txtCity.Text, txtState.Text, txtZip.Text)
RaiseEvent OnButtonClick(Me, retvals)
End Sub
Private Sub CancelButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Dim retvals As New MyControlEventArgs(False, txtName.Text, txtAddress.Text, txtCity.Text, txtState.Text, txtZip.Text)
RaiseEvent OnButtonClick(Me, retvals)
End Sub
End Class
private void OKButton_Click(object sender, System.EventArgs e)
{
MyControlEventArgs retvals = new MyControlEventArgs(true,
txtName.Text,
txtAddress.Text,
txtCity.Text,
txtState.Text,
txtZip.Text);
OnButtonClick(this, retvals);
}
private void CancelButton_Click(object sender, System.EventArgs e)
{
MyControlEventArgs retvals = new MyControlEventArgs(false,
txtName.Text,
txtAddress.Text,
txtCity.Text,
txtState.Text,
txtZip.Text);
OnButtonClick(this, retvals);
}
为程序集赋予强名称并生成该程序集
若要使 WPF 应用程序引用该程序集,该程序集必须具有强名称。若要创建强名称,请使用 Sn.exe 创建一个密钥文件并将其添加到项目的 AssemblyInfo.cs 文件中。
打开一个 Visual Studio 命令提示窗口。为此,请单击“开始”菜单,然后依次选择“所有程序”/“Microsoft Visual Studio 2008”/“Visual Studio Tools”/“Visual Studio 2008 命令提示”。这将启动一个控制台窗口,该窗口带有自定义的环境变量。
在命令提示符处,使用“cd”命令转至您的项目文件夹。
运行以下命令以生成一个名为 MyControls.snk 的密钥文件。
Sn.exe -k MyControls.snk
若要将密钥文件包括在项目中,请在解决方案资源管理器中右击项目名称,并打开“属性”对话框。选择“签名”选项卡,并输入密钥文件的名称。
生成该程序集。此生成行为将生成一个名为 MyControls.dll 的 DLL。
使用 Windows Presentation Foundation 实现宿主应用程序
WPF 宿主应用程序使用 WindowsFormsHost 控件来承载 MyControl1。该应用程序处理 OnButtonClick 事件以接收来自控件的数据。它还具有选项按钮集合,可用于从 WPF 页更改控件的一些属性。下图演示已完成的应用程序。
完整的应用程序,显示 Windows Presentation Foundation 页中嵌入的控件
创建项目
若要开始创建项目,请执行以下操作:
打开 Visual Studio,并选择“新建项目”。
选择“WPF 浏览器应用程序”模板。
将项目命名为 WpfHost,并单击“确定”以打开该项目。
您还将需要添加一个对包含 MyControl1 的 DLL 的引用。以下是添加该引用的最简单的方法。
在解决方案资源管理器中右击项目名称,并启动“添加引用”对话框。
单击“浏览”选项卡,并浏览至该 Windows 窗体控件的输出文件夹。对于本示例,该文件夹为 MyControls\bin\Debug。
选择包含该控件的 DLL,然后单击“确定”将其添加到引用列表中。对于在 Windows Presentation Foundation 中承载 Windows 窗体复合控件的示例,该 DLL 命名为 MyControls.dll。
在解决方案资源管理器中,添加一个对名为 WindowsFormsIntegration.dll 的 WindowsFormsIntegration 程序集的引用。
实现基本布局
宿主应用程序的用户界面 (UI) 在 Page1.xaml 中实现。此文件包含定义页面布局并承载 Windows 窗体 控件的可扩展应用程序标记语言 (XAML) 标记。该页分为三个区域:
“控件属性”面板,该面板包含可用于修改所承载控件的各个属性的选项按钮集合。
“来自控件的数据”[Data from Control]面板,该面板包含若干显示从所承载控件返回的数据的 TextBlock 元素。
所承载的控件自身。
下面的代码示例演示基本布局代码。该示例中省略了承载 MyControl1 所需的标记代码,但后面将对其进行讨论。将 Page1.xaml 中的代码替换为以下代码。
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Page1"
xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
Loaded="Init">
<DockPanel>
<DockPanel.Resources>
<Style x:Key="inlineText" TargetType="{x:Type Inline}">
<Setter Property="FontWeight" Value="Normal"/>
</Style>
<Style x:Key="titleText" TargetType="{x:Type TextBlock}">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Margin" Value="10,5,10,0"/>
</Style>
</DockPanel.Resources>
<StackPanel Orientation="Vertical"
DockPanel.Dock="Left"
Background="Bisque"
Width="250">
<TextBlock Margin="10,10,10,10"
FontWeight="Bold"
FontSize="12">Control Properties</TextBlock>
<TextBlock Style="{StaticResource titleText}">Background Color</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalBackColor"
IsChecked="True"
Click="BackColorChanged">Original</RadioButton>
<RadioButton Name="rdbtnBackGreen"
Click="BackColorChanged">LightGreen</RadioButton>
<RadioButton Name="rdbtnBackSalmon"
Click="BackColorChanged">LightSalmon</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Foreground Color</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalForeColor"
IsChecked="True"
Click="ForeColorChanged">Original</RadioButton>
<RadioButton Name="rdbtnForeRed"
Click="ForeColorChanged">Red</RadioButton>
<RadioButton Name="rdbtnForeYellow"
Click="ForeColorChanged">Yellow</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Family</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalFamily"
IsChecked="True"
Click="FontChanged">Original</RadioButton>
<RadioButton Name="rdbtnTimes"
Click="FontChanged">Times New Roman</RadioButton>
<RadioButton Name="rdbtnWingdings"
Click="FontChanged">Wingdings</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Size</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalSize"
IsChecked="True"
Click="FontSizeChanged">Original</RadioButton>
<RadioButton Name="rdbtnTen"
Click="FontSizeChanged">10</RadioButton>
<RadioButton Name="rdbtnTwelve"
Click="FontSizeChanged">12</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Style</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnNormalStyle"
IsChecked="True"
Click="StyleChanged">Original</RadioButton>
<RadioButton Name="rdbtnItalic"
Click="StyleChanged">Italic</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Weight</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalWeight"
IsChecked="True"
Click="WeightChanged">
Original
</RadioButton>
<RadioButton Name="rdbtnBold"
Click="WeightChanged">Bold</RadioButton>
</StackPanel>
</StackPanel>
<WindowsFormsHost Name="wfh"
DockPanel.Dock="Top"
Height="300">
<mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>
<StackPanel Orientation="Vertical"
Height="Auto"
Background="LightBlue">
<TextBlock Margin="10,10,10,10"
FontWeight="Bold"
FontSize="12">Data From Control</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Name: <Span Name="txtName" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Street Address: <Span Name="txtAddress" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
City: <Span Name="txtCity" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
State: <Span Name="txtState" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Zip: <Span Name="txtZip" Style="{StaticResource inlineText}"/>
</TextBlock>
</StackPanel>
</DockPanel>
</Page>
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfHost.Page1"
xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
Loaded="Init">
<DockPanel>
<DockPanel.Resources>
<Style x:Key="inlineText" TargetType="{x:Type Inline}">
<Setter Property="FontWeight" Value="Normal"/>
</Style>
<Style x:Key="titleText" TargetType="{x:Type TextBlock}">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Margin" Value="10,5,10,0"/>
</Style>
</DockPanel.Resources>
<StackPanel Orientation="Vertical"
DockPanel.Dock="Left"
Background="Bisque"
Width="250">
<TextBlock Margin="10,10,10,10"
FontWeight="Bold"
FontSize="12">Control Properties</TextBlock>
<TextBlock Style="{StaticResource titleText}">Background Color</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalBackColor"
IsChecked="True"
Click="BackColorChanged">Original</RadioButton>
<RadioButton Name="rdbtnBackGreen"
Click="BackColorChanged">LightGreen</RadioButton>
<RadioButton Name="rdbtnBackSalmon"
Click="BackColorChanged">LightSalmon</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Foreground Color</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalForeColor"
IsChecked="True"
Click="ForeColorChanged">Original</RadioButton>
<RadioButton Name="rdbtnForeRed"
Click="ForeColorChanged">Red</RadioButton>
<RadioButton Name="rdbtnForeYellow"
Click="ForeColorChanged">Yellow</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Family</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalFamily"
IsChecked="True"
Click="FontChanged">Original</RadioButton>
<RadioButton Name="rdbtnTimes"
Click="FontChanged">Times New Roman</RadioButton>
<RadioButton Name="rdbtnWingdings"
Click="FontChanged">Wingdings</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Size</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalSize"
IsChecked="True"
Click="FontSizeChanged">Original</RadioButton>
<RadioButton Name="rdbtnTen"
Click="FontSizeChanged">10</RadioButton>
<RadioButton Name="rdbtnTwelve"
Click="FontSizeChanged">12</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Style</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnNormalStyle"
IsChecked="True"
Click="StyleChanged">Original</RadioButton>
<RadioButton Name="rdbtnItalic"
Click="StyleChanged">Italic</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Weight</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalWeight"
IsChecked="True"
Click="WeightChanged">
Original
</RadioButton>
<RadioButton Name="rdbtnBold"
Click="WeightChanged">Bold</RadioButton>
</StackPanel>
</StackPanel>
<WindowsFormsHost Name="wfh"
DockPanel.Dock="Top"
Height="300">
<mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>
<StackPanel Orientation="Vertical"
Height="Auto"
Background="LightBlue">
<TextBlock Margin="10,10,10,10"
FontWeight="Bold"
FontSize="12">Data From Control</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Name: <Span Name="txtName" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Street Address: <Span Name="txtAddress" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
City: <Span Name="txtCity" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
State: <Span Name="txtState" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Zip: <Span Name="txtZip" Style="{StaticResource inlineText}"/>
</TextBlock>
</StackPanel>
</DockPanel>
</Page>
第一个 StackPanel 元素包含若干 RadioButton 控件集,使用这些控件可以修改所承载控件的各个默认属性。该元素之后是 WindowsFormsHost 元素,此元素承载 MyControl1。最后的 StackPanel 元素包含若干显示从所承载控件返回的数据的 TextBlock 元素。这些元素的排序以及 Dock 和 Height 属性设置无间隙并且不失真地将所承载的控件嵌入到页面中。
承载控件
下面是上一个代码示例的已编辑版本,重点说明承载 MyControl1 所需的元素。
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Page1"
xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
Loaded="Init">
...
<WindowsFormsHost Name="wfh"
DockPanel.Dock="Top"
Height="300">
<mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfHost.Page1"
xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
Loaded="Init">
...
<WindowsFormsHost Name="wfh"
DockPanel.Dock="Top"
Height="300">
<mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>
xmlns 命名空间映射属性创建一个对包含所承载控件的 MyControls 命名空间的引用。通过该映射,可以在 XAML 中将 MyControl1 表示为 <mcl:MyControl1>。
此代码示例中的以下两个元素处理承载:
WindowsFormsHost 表示 WindowsFormsHost 元素,通过该元素可以在 WPF 页面上承载 Windows 窗体控件。
mcl:MyControl1,表示 MyControl1,它被添加到 WindowsFormsHost 元素的子集合。因此,该 Windows 窗体控件呈现为 WPF 页的一部分,并且您可以从该页与此控件通信。
实现代码隐藏文件
代码隐藏文件 Page1.xaml.cs 包含用于实现上一节中所述的 UI 功能的程序代码。主要任务是:
将一个事件处理程序附加到 MyControl1 的 OnButtonClick 事件。
基于选项按钮集合的设置方式修改 MyControl1 的各个属性。
显示由控件收集的数据。
初始化应用程序
初始化代码包含在页面的 Loaded 事件的事件处理程序中,并将该事件处理程序附加到控件的 OnButtonClick 事件。将以下代码复制到 Page1.xaml.cs 的 Page1 类中。
Class Page1
Inherits Page
Private app As Application
Private myWindow As NavigationWindow
Private initFontWeight As FontWeight
Private initFontSize As [Double]
Private initFontStyle As FontStyle
Private initBackBrush As SolidColorBrush
Private initForeBrush As SolidColorBrush
Private initFontFamily As FontFamily
Private UIIsReady As Boolean = False
Private Sub Init(ByVal sender As Object, ByVal e As RoutedEventArgs)
app = System.Windows.Application.Current
myWindow = CType(app.MainWindow, NavigationWindow)
myWindow.SizeToContent = SizeToContent.WidthAndHeight
wfh.TabIndex = 10
initFontSize = wfh.FontSize
initFontWeight = wfh.FontWeight
initFontFamily = wfh.FontFamily
initFontStyle = wfh.FontStyle
initBackBrush = CType(wfh.Background, SolidColorBrush)
initForeBrush = CType(wfh.Foreground, SolidColorBrush)
Dim mc As MyControl1 = wfh.Child
AddHandler mc.OnButtonClick, AddressOf Pane1_OnButtonClick
UIIsReady = True
End Sub
public partial class Page1 : Page
{
private Application app;
private NavigationWindow myWindow;
FontWeight initFontWeight;
Double initFontSize;
FontStyle initFontStyle;
SolidColorBrush initBackBrush;
SolidColorBrush initForeBrush;
FontFamily initFontFamily;
bool UIIsReady = false;
private void Init(object sender, EventArgs e)
{
app = System.Windows.Application.Current;
myWindow = (NavigationWindow)app.MainWindow;
myWindow.SizeToContent = SizeToContent.WidthAndHeight;
wfh.TabIndex = 10;
initFontSize = wfh.FontSize;
initFontWeight = wfh.FontWeight;
initFontFamily = wfh.FontFamily;
initFontStyle = wfh.FontStyle;
initBackBrush = (SolidColorBrush)wfh.Background;
initForeBrush = (SolidColorBrush)wfh.Foreground;
(wfh.Child as MyControl1).OnButtonClick += new MyControl1.MyControlEventHandler(Pane1_OnButtonClick);
UIIsReady = true;
}
由于已将前面讨论的 XAML 代码 MyControl1 添加到 WindowsFormsHost 元素的子元素集合中,因此您可以强制转换 WindowsFormsHost 元素的 Child,以获取对 MyControl1 的引用。然后,可以使用该引用将事件处理程序附加到 OnButtonClick。
除了提供对控件自身的引用之外,WindowsFormsHost 还公开控件的许多属性,您可以从该页操作这些属性。初始化代码将这些值分配给私有全局变量,以便以后在应用程序中使用。
处理 OnButtonClick 事件
当用户单击控件的任何一个按钮时,MyControl1 将引发 OnButtonClick 事件。将下面的代码添加到 Page1 类中。
'Handle button clicks on the Windows Form control
Private Sub Pane1_OnButtonClick(ByVal sender As Object, ByVal args As MyControlEventArgs)
txtName.Inlines.Clear()
txtAddress.Inlines.Clear()
txtCity.Inlines.Clear()
txtState.Inlines.Clear()
txtZip.Inlines.Clear()
If args.IsOK Then
txtName.Inlines.Add(" " + args.MyName)
txtAddress.Inlines.Add(" " + args.MyStreetAddress)
txtCity.Inlines.Add(" " + args.MyCity)
txtState.Inlines.Add(" " + args.MyState)
txtZip.Inlines.Add(" " + args.MyZip)
End If
End Sub
End Class
//Handle button clicks on the Windows Form control
private void Pane1_OnButtonClick(object sender, MyControlEventArgs args)
{
txtName.Inlines.Clear();
txtAddress.Inlines.Clear();
txtCity.Inlines.Clear();
txtState.Inlines.Clear();
txtZip.Inlines.Clear();
if (args.IsOK)
{
txtName.Inlines.Add( " " + args.MyName );
txtAddress.Inlines.Add( " " + args.MyStreetAddress );
txtCity.Inlines.Add( " " + args.MyCity );
txtState.Inlines.Add( " " + args.MyState );
txtZip.Inlines.Add( " " + args.MyZip );
}
}
文本框中的数据将被打包到 MyControlEventArgs 对象中。如果用户单击“OK”(确定)按钮,事件处理程序将提取数据,并在 MyControl1 下面的面板中显示这些数据。
修改控件的属性
WindowsFormsHost 元素公开所承载控件的若干默认属性。因此,您可以更改控件的外观,以便与页面的样式更加匹配。使用左侧面板中的选项按钮集合,可以修改若干颜色和字体属性。每个按钮集合都有用于 Click 事件的处理程序,该处理程序将检测用户的选项按钮选择,并更改控件上的相应属性。将下面的代码复制到 Page1 类中。现在可以编译并运行应用程序。
Private Sub BackColorChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnBackGreen) Then
wfh.Background = New SolidColorBrush(Colors.LightGreen)
ElseIf sender.Equals(rdbtnBackSalmon) Then
wfh.Background = New SolidColorBrush(Colors.LightSalmon)
ElseIf UIIsReady = True Then
wfh.Background = initBackBrush
End If
End Sub
Private Sub ForeColorChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnForeRed) Then
wfh.Foreground = New SolidColorBrush(Colors.Red)
ElseIf sender.Equals(rdbtnForeYellow) Then
wfh.Foreground = New SolidColorBrush(Colors.Yellow)
ElseIf UIIsReady = True Then
wfh.Foreground = initForeBrush
End If
End Sub
Private Sub FontChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnTimes) Then
wfh.FontFamily = New FontFamily("Times New Roman")
ElseIf sender.Equals(rdbtnWingdings) Then
wfh.FontFamily = New FontFamily("Wingdings")
ElseIf UIIsReady = True Then
wfh.FontFamily = initFontFamily
End If
End Sub
Private Sub FontSizeChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnTen) Then
wfh.FontSize = 10
ElseIf sender.Equals(rdbtnTwelve) Then
wfh.FontSize = 12
ElseIf UIIsReady = True Then
wfh.FontSize = initFontSize
End If
End Sub
Private Sub StyleChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnItalic) Then
wfh.FontStyle = FontStyles.Italic
ElseIf UIIsReady = True Then
wfh.FontStyle = initFontStyle
End If
End Sub
Private Sub WeightChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnBold) Then
wfh.FontWeight = FontWeights.Bold
ElseIf UIIsReady = True Then
wfh.FontWeight = initFontWeight
End If
End Sub
private void BackColorChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnBackGreen)
wfh.Background = new SolidColorBrush(Colors.LightGreen);
else if (sender == rdbtnBackSalmon)
wfh.Background = new SolidColorBrush(Colors.LightSalmon);
else if (UIIsReady == true)
wfh.Background = initBackBrush;
}
private void ForeColorChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnForeRed)
wfh.Foreground = new SolidColorBrush(Colors.Red);
else if (sender == rdbtnForeYellow)
wfh.Foreground = new SolidColorBrush(Colors.Yellow);
else if (UIIsReady == true)
wfh.Foreground = initForeBrush;
}
private void FontChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnTimes)
wfh.FontFamily = new FontFamily("Times New Roman");
else if (sender == rdbtnWingdings)
wfh.FontFamily = new FontFamily("Wingdings");
else if (UIIsReady == true)
wfh.FontFamily = initFontFamily;
}
private void FontSizeChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnTen)
wfh.FontSize = 10;
else if (sender == rdbtnTwelve)
wfh.FontSize = 12;
else if (UIIsReady == true)
wfh.FontSize = initFontSize;
}
private void StyleChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnItalic)
wfh.FontStyle = FontStyles.Italic;
else if (UIIsReady == true)
wfh.FontStyle = initFontStyle;
}
private void WeightChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnBold)
wfh.FontWeight = FontWeights.Bold;
else if (UIIsReady == true)
wfh.FontWeight = initFontWeight;
}
请参见
任务
演练:在 Windows Presentation Foundation 中承载 Windows 窗体控件
概念
演练:在 Windows 窗体中承载 Windows Presentation Foundation 控件