Visual C#.NET提供了通过“继承”创建功能强大的自定义控件的能力。如果要扩展现有控件的功能,就可以通过继承创建由现有控件导出的控件。通过继承所创建的控件不仅可以保留标准Windows窗体控件的所有固有功能和可视属性,还可以并入自定义功能。
下面通过创建从现有Windows窗体控件继承的控件介绍定制控件的一般过程。读者可以自行尝试创建从Control类和UserControl类继承的控件。本例创建一个名为StringButton的简单控件,该控件将继承标准Windows窗体按钮的功能,并公开一个名为ButtonString的自定义属性。具体过程如下:
(1) 创建StringButtonLib控件库和StringButton控件。打开“新建项目”对话框,在“C#项目”列表中,选择“Windows控件库”项目模板,然后在“名称”框中输入StringButtonLib并单击“确定”按钮,进入如图9-30所示的控件设计器。
创建新项目时,应指定其名称以便设置根命名空间、程序集名称和项目名称,并确保默认组件位于正确的命名空间中。默认情况下,项目名称StringButtonLib也会分配到根命名空间中。根命名空间用于限定程序集中的组件名。

(2) 在属性窗口中,将“文件名”属性更改为StringButton.cs。
(3) 在解决方案资源管理器中,右键单击UserControl1.cs,并从右键菜单中选择“查看代码”以切换到代码编辑器。找到类定义语句public class UserControl1,将UserControl1更改为StringButton以更改控件的名称。找到构造函数public UserControl1(),将它更改为public StringButton()。将该控件从System.Windows.Forms.UserControl继承更改为从System.Windows.Forms.Button继承。这样就允许定制控件继承Button控件的所有功能。
此时设计器已不再可用,如图9-31所示。因为Button控件自己完成绘制,所以无法在设计器中修改它的外观。除非在代码中对其进行修改,否则它的可视化表示形式将与它从中继承的类即Button的表示形式完全相同。

(4) 将属性添加到继承的控件中。继承的Windows窗体控件有很多用途,其中之一就是创建与标准Windows窗体控件的外观相同、但公开自定义属性的控件。本例中将向控件中添加名为ButtonString的属性。
切换到代码编辑视图,找到类定义语句,在紧靠“{”的后面输入下面的代码:
//创建用于保存属性值的私有变量
private string varString;
// 声明属性
public string ButtonString
{
// 获取属性值的方法
get
{
return varString;
}
// 设值属性值的方法
set
{
varString = value;
}
}
上述代码包含了设置和获取ButtonString属性的方法。get语句设置返回到存储在私有变量varString中的值,set语句通过使用value关键字设置私有变量的值。
(5) 生成控件。在“生成”菜单中单击“生成StringButtonLib”,输出窗口应提示生成成功。
(6) 创建测试项目。控件不是独立的项目,它们必须寄宿在容器中。若要测试控件,就必须提供一个运行该控件的测试项目。
打开“新建项”对话框,选择“Visual C#项目”节点,然后单击“Windows应用程序”,在“名称”框中输入test。单击“确定”按钮回到.NET环境。
(7) 在解决方案资源管理器中,右键单击test项目的“引用”节点,并从快捷菜单中选择“添加引用”以打开“添加引用”对话框。然后打开“项目”选项卡,如图9-32所示。双击StringButtonLib项目,使该项目此时出现在“选定的组件”窗格中。最后单击“确定”按钮回到设计器。

(8) 添加引用后,需要将新控件添加到工具箱。如果该控件已经出现在工具箱中,则可以跳过本步骤。
右键单击“工具箱”,然后从快捷菜单中选择“自定义工具箱”以打开如图9-33所示的“自定义工具箱”对话框。然后选择“.NET框架组件”选项卡并单击“浏览”按钮。浏览到StringButtonLib/bin/debug文件夹并选择StringButton.dll,使StringButton出现在“自定义工具箱”对话框的组件列表中。

在“自定义工具箱”对话框中,单击使StringButton旁的方框显示“Ö”并关闭窗口。回到设计器后可以看到StringButton已经被添加到“工具箱”上选定的选项卡上了,如图9-34所示。

(9) 将控件添加到窗体。在“工具箱”中选中标记为StringButton的图标并添加到窗体中,窗体中显示一个名为“StringButton1”的定制控件。在“属性”窗口中检查该控件的属性,可以看到它们与标准按钮公开的属性相同,不同的是多了一个附加属性ButtonString。将ButtonString属性设置为“我的第一个定制控件”。再在窗体中适当位置添加一个文本框,并设置其Text属性为空。
(10) 添加事件处理代码。双击StringButton1以打开代码编辑器并显示StringButton1_Click事件,在当前光标位置输入以下代码:
textBox1.Text=StringButton1.ButtonString;
(11) 在解决方案资源管理器中,右键单击test,然后从快捷菜单中选择“设为启动项目”。
(12) 按F5键运行该项目,出现Form1。单击StringButton1按钮,文本框中显示“我的第一个定制控件”,如图9-35所示。这说明继承控件的ButtonString属性已经通过StringButton1_Click方法传递到文本框。这样,StringButton控件便继承了标准Windows窗体按钮的所有功能,但是公开了一个附加的自定义属性。
