C_自定义控件从入门到精通
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
自定义控件从入门到精通
一、概述
Windows 窗体控件是可再次使用的组件,它们封装了用户界面功能,并且可以用于客户端Windows 应用程序。“Windows 窗体”不仅提供了许多现成控件,还提供了自行开发控件的基础结构。可以组合现有控件、扩展现有控件或创作自己的自定义控件。Windows 窗体控件是从System.Windows.Forms.Control直接或间接派生的类。以下列表描述了开发Windows 窗体控件的常见方案:
·组合现有控件来创作一个复合控件。
复合控件封装有一个可以作为控件重复使用的用户界面。可视化设计器为创建复合控件提供了有力的支持。要创作一个派生自erControl的复合控件。基类UserControl 为子控件提供了键盘路由并使子控件可以作为一个组进行工作。
·扩展现有控件,对其进行自定义或为其添加功能。
可以通过从任何Windows 窗体控件派生控件并重写或添加属性、方法和事件的方式来自定义Windows 窗体控件。
·创作一个不是通过组合或扩展现有控件而形成的控件。
在这种方案中,需从基类System.Windows.Forms.Control派生控件。可以添加和重写基类的属性、方法和事件,来制作功能强大,能满足自己需求的控件。
Windows 窗体控件的基类System.Windows.Forms.Control 为客户端Windows 应用程序中的外观显示提供了所需的
途径。Control 提供了一个窗口句柄,用来处理消息路由并提供鼠标和键盘事件及许多其他用户界面事件。还提供了高级布局,并具有用于外观显示的特定属性,如ForeColor、BackColor、Height、Width 和许多其他属性。此外,它还提供了安全性、线程支持以及与ActiveX 控件的交互性。由于基类提供了很多基础结构,使得开发自己的Windows 窗体控件变得相对简单。
二、编写简单的自定义控件
2.1、简单控件例子
下面的示例创建一个简单控件,该控件通过处理Paint 事件显示其Text 属性的值。为了创建此控件和处理事件,必须创建一个从Control 继承的类,并创建一个重写OnPaint 方法的方法。
public class HelloWorldControl : Control
{
protected override void OnPaint(PaintEventArgs e)
{
RectangleF rect = new RectangleF(ClientRectangle.X,
ClientRectangle.Y,
ClientRectangle.Width,
ClientRectangle.Height);
e.Graphics.DrawString(this.Text, Font, new SolidBrush(ForeColor), rect);
}
2.2、我们在VS2005中创建自定义控件的步骤:
1. 打开vs2005,文件/新建/项目。
2. 出现“新建项目”对话框。
3. 在“名称”框中,键入项目名称,“位置”框选择要存储的位置。
4. 从“语言”列表中选择要使用的编程语言。
5. 单击“添加”,这时一个自定义控件工程已经建成,生成一下,就制作了一个简单的自定义控件,只不过没有任何功能。
6. 向新用户控件添加任何标记和控件,并为该用户控件添加执行的所有任务(例如,处理控件事件或从数据源读取数据)添加代码。
2.3、检查控件的设计时行为
1. 启动VS2005。
2. 通过从“文件”菜单单击/新建/项目/Windows应用程序,添加新窗体。
3. 右键“工具箱/选择项…”,在弹出的“选择工具箱项”对话框中点下面的浏览按钮选择要使用控件的DLL;确定后,该控件出现在工具箱的底部。
4. 选择该控件并将其添加到窗体中。将看到该控件出现在窗体上。
5. 如果从上一个示例添加控件,您将注意到即使如此简单的控件都具有一整套属性和广泛的设计时行为。此默认行为是从Control 类继承的。
三、为控件添加属性
控件应该定义属性而不是公共字段,因为可视化设计器在属性浏览器中显示属性,而不显示字段。属性就像智能字段。属性通常具有带访问函数的专用数据成员,在语法上属性被作为类的字段进行访问。(虽然属性可以具有不同的访问级别,但此处的讨论将重点放在公共访问这种更加常见的情况上。
属性定义通常由以下两部分组成:
1、专用数据成员的定义。
private int number = 0;
2、使用属性声明语法对公共属性进行的定义。
该语法通过get 和set 访问函数将专用数据成员和公共属性关联起来。
public int MyNumber
{
{
return number;
}
set
{
number = value;
}
}
value 这个术语是属性定义语法中的一个关键字。在呼叫代码中,将变量value 分配给属性。value 的类型必须同它被分配到的属性的声明类型相同。
虽然属性定义中通常包含专用数据成员,但这不是必需的。get 访问器不用访问私有数据成员就可以返回值。get 方法返回系统时间的属性就属于这种情况。属性启用数据隐藏,访问器方法隐藏属性的实现。
定义属性时需考虑以下重要的注意事项:
1、必须将属性应用于定义的属性。属性用来指定设计器显示属性的方式。
2、如果改变属性将影响控件的外观显示,请从set 访问器中调用Invalidate 方法(从Control 继承该方法)。Invalidate 随后调用OnPaint 方法,该方法将重新绘制控件。为提高效率起见,对Invalidate 的多次调用将产生对OnPaint 的一次调用。
3、 .NET Framework 类库为常见数据类型(如整数、小数、布尔值和其他数据)提供了类型转换器。类型转换器的目的通常是用来提供字符串到数值的转换(从字符串数据转换为其他数据类型)。常见数据类型与默认类型转换器(将数值转换为字符串,并将字符串转换为相应数据类型)相关联。如果定义了自定义(即,非标准)数据类型的属性,则应用的属性必须将类型转换器指定为与该属性相关联。还可以使用属性使自定义UI 类型编辑器与某个属性相关联。UI 类型编辑器提供了一个用来编辑属性或数据类型的用户界面。颜色选择器是UI 类型编辑器的一个示例。
例:首先创建一个名为DrawingMode 的简单枚举。
public enum DrawingMode
{
Happy = 0,
Sad = 1,
Angry = 2
}
接着,向该控件添加 MyDrawingMode 属性