【WinForm窗体控件开发】之一 概述
我们在实际开发Winform程序时难免要使用到WinForm提供控件。但是随着开发的深入,我们发现MS提供给我们的控件不能实现我们想要的功能了(例如:我想要一个只能输入数字的TextBox,这里我只是列举一个简单的例子,其实这个功能我们完全可以在TextBoxChanged Event中做各种的判断,但是如果这个特殊的TextBox要在整个项目中使用N多次的话,上面的这种做法无疑会造成Code冗余、可维护性的诸多问题),那我们应该怎么办呢?开发自定义窗体控件,在自定义窗体控件中实现我们想要的功能。
自定义控件都是直接或间接继承自Control基控件类的,所以我们首先简单了解下Control基控件类和自定义控件的分类以及建议(引自MSDN):
基控件类
Control 类是 Windows 窗体控件的基类。它提供了在 Windows 窗体应用程序中进行可视显示所需的基础结构。
Control 类执行下列任务,以便在 Windows 窗体应用程序中提供可视显示:
- 公开窗口句柄。
- 管理消息路由。
- 提供鼠标和键盘事件,以及许多其他用户界面事件。
- 提供高级布局功能。
- 包含特定于可视显示的许多属性,如 ForeColor、BackColor、Height 和 Width。
- 为 Windows 窗体控件充当 Microsoft® ActiveX® 控件提供必需的安全和线程支持。
由于基类提供了很多基础结构,使得开发自己的 Windows 窗体控件变得相对简单。
控件的种类
Windows 窗体支持三种用户定义的控件:复合控件、扩展控件和自定义控件。以下各节分别描述各种控件,并就如何选择项目中使用的控件种类提供建议。
复合控件
复合控件是封装在公共容器内的 Windows 窗体控件的集合。这种控件有时称为“用户控件”。包含的控件称为“构成控件”。
复合控件包含与每个包含的 Windows 窗体控件相关联的所有固有功能,允许您有选择地公开和绑定它们的属性。复合控件还提供了大量的默认键盘处理功能,您不需要任何额外的开发。
例如,可以生成复合控件以显示来自数据库的客户地址数据。此控件可以包括一个用来显示数据库字段的 DataGridView 控件、一个用来处理到数据源的绑定的 BindingSource 和一个用来在记录之间移动的 BindingNavigator 控件。可以有选择地公开数据绑定属性,还可以将整个控件打包并在不同应用程序之间重复使用。有关这种复合控件的示例,请参见如何:应用 Windows 窗体控件中的属性。
若要创作复合控件,请从 UserControl 类派生。基类 UserControl 为子控件提供了键盘路由并使子控件可以作为一个组进行工作。有关更多信息,请参见开发复合 Windows 窗体控件。
建议:
在下列情况下,从 UserControl 类继承:
- 要将若干个 Windows 窗体控件的功能合成一个可重新使用的单元。
扩展控件
可以从任何现有的 Windows 窗体控件导出继承控件。此方法使您得以保留 Windows 窗体控件的所有固有功能,然后通过添加自定义属性、方法或其他功能扩展此固有功能。可以使用此选项重写基控件的绘制逻辑,然后更改该控件的外观以扩展其用户界面。
例如,可以创建一个由 Button 控件派生的控件,用于跟踪用户的单击次数。
在某些控件中,也可以通过重写基类的 OnPaint 方法为图形用户界面添加自定义外观。对于跟踪单击次数的扩展按钮,可以重写 OnPaint 方法来调用 OnPaint 的基实现,然后在 Button 控件的工作区的一角绘制单击计数。
建议:
处于下列情况时继承 Windows 窗体控件:
- 大多数所需的功能已经与现有的 Windows 窗体控件相同。
- 不需要自定义图形用户界面,或者想为现有控件设计一个新的图形用户界面。
自定义控件
创建控件的另一种方法是通过从 Control 继承从头开始创建一个控件。Control 类提供控件所需的所有基本功能(包括鼠标和键盘处理事件),但不提供控件特定的功能或图形界面。
与通过从 UserControl 或现有 Windows 窗体控件继承创建控件相比,通过从 Control 类继承创建控件需要耗费更多的心思和精力。由于大量的实现将留给您进行,因此,您的控件可以具有比复合控件或扩展控件更大的灵活性,而且您可以使控件完全满足自己的需要。
若要实现自定义控件,必须编写该控件的 OnPaint 事件的代码,以及所需的任何功能特定的代码。还可以重写 WndProc 方法并直接处理窗口消息。这是创建控件的最强大的方法,但是要有效地使用此技术,需要熟悉 Microsoft Win32® API。
时钟控件即是一个自定义控件,它复制模拟时钟的外观和行为。自定义绘制将被调用来促使时钟指针走动,以响应内部 Timer 组件的 Tick 事件。有关更多信息,请参见如何:开发简单的 Windows 窗体控件。
建议
在下列情况下,从 Control 类继承:
- 想要提供控件的自定义图形化表示形式。
- 需要实现无法从标准控件获得的自定义功能。
ActiveX 控件
略
关于自定义控件开发的建议,我想这里应该引用一下MSDN的一段话:
从 Windows 窗体控件继承
可以从任何现有的 Windows 窗体控件导出继承控件。此方法使您得以保留 Windows 窗体控件所有固有功能,然后通过添加自定义属性、方法或其他功能扩展此固有功能。例如,可以创建一个从 TextBox 派生的控件,该控件只接受数字并能自动将输入转换为值。这样的控件可能包含验证代码,每当文本框中的文本发生更改时就会调用此代码,另外,控件还可能有一个附加的“值”属性。在某些控件中,也可以通过重写基类的 OnPaint 方法将自定义外观添加到控件的图形接口上。
处于下列情况时继承 Windows 窗体控件:
- 大多数所需的功能已经与现有的 Windows 窗体控件相同。
- 不需要自定义图形接口,或者想为现有控件设计一个新的图形前端。
从 UserControl 类继承
用户控件是封装在公共容器内的 Windows 窗体控件的集合。此容器包含与每个 Windows 窗体控件相关联的所有固有功能,允许您有选择地公开和绑定它们的属性。用户控件的例子之一可能是已生成的显示数据库中客户地址数据的控件。该控件可能包括几个用来显示字段的文本框,几个用来通过记录定位的按钮 (Button) 控件。可以有选择地公开数据绑定属性,可以将整个控件打包并在应用程序之间重复使用。
在下列情况下,从 UserControl 类继承:
- 要将若干个 Windows 窗体控件的功能合成一个可重新使用的单元。
从 Control 类继承
创建控件的另一种方式是通过从 Control 继承从头创建一个控件。Control 类提供控件(例如事件)所需的所有基本功能,但不提供控件特定的功能或图形界面。与通过从用户控件或现有 Windows 窗体控件继承创建控件相比,通过从 Control 类继承创建控件需要耗费更多的心思和精力。因为作者必须为控件的 OnPaint 事件编写代码以及所需的任何功能特定代码,但同时也允许作者根据自己的需要,灵活地自定义调整控件。时钟控件即是一个自定义控件,它复制模拟时钟的外观和操作,自定义绘制将被调用来促使时钟指针走动,以响应内部计时器组件的 Tick 事件。
在下列情况下,从 Control 类继承:
- 想要提供控件的自定义图形化表示形式。
- 需要实现无法从标准控件获得的自定义功能。