组件开发.ppt

上传人:本田雅阁 文档编号:2753948 上传时间:2019-05-11 格式:PPT 页数:30 大小:175.01KB
返回 下载 相关 举报
组件开发.ppt_第1页
第1页 / 共30页
组件开发.ppt_第2页
第2页 / 共30页
组件开发.ppt_第3页
第3页 / 共30页
组件开发.ppt_第4页
第4页 / 共30页
组件开发.ppt_第5页
第5页 / 共30页
点击查看更多>>
资源描述

《组件开发.ppt》由会员分享,可在线阅读,更多相关《组件开发.ppt(30页珍藏版)》请在三一文库上搜索。

1、组件开发,Zhanghz 2006.12.24,本章概要,日常开发中,经常需要创建一些可以重用的控件。本章介绍如何开发组件和Windows窗体控件的技术,主要介绍组件和控件的创建、在组件中使用事件、扩展已有组件、从Control类既成创建新控件和为控件添加设计时的功能等。 纲要 基本概念 在组件中使用事件 开发Windows窗体控件,基本概念,组件的概念 实现了接口System.ComponentModel.IComponent的类,或者是从System.ComponentModel.Component类以及其他实现了IComponent接口的类得到的派生类。 可以被重用,也可以和其他对象进行

2、交互。 也可以使用结构来实现组件,但是结构不能用来派生新类,通常使用类来实现组件。 组件的使用 通常都要包含在一个命名空间中,在创建组件时需要使用Namespace语句为组件声明相应的命名空间。,组件实质是类,可以实现继承的方法和属性,也可以添加自己的方法、属性和事件等 实际编程中,通常使用属性来代替公共字段。因为在VS.NET的可视化设计器中会显示组件的属性,而不显示组件字段。 使用属性可以在访问时进行验证或执行一些复杂的操作,要比字段来得灵活。 开发组件要注意组件的创建和销毁。 构造函数和析构函数 析构函数的调用时间不确定,可能会造成组件使用完成与析构函数调用之间有延迟,因此,要同时在组件

3、中实现Dispose方法,以便通过它来明确释放组件占用的资源。,组件示例,using System; Namespace MyNamespace /定义组件类 public class MyComponent:System.ComponentModel.Component private int m_myProperty; /声明字段 public MyComponent() public int Myproperty /声明属性 get set protected override void Dispose( bool disposing ) if(disposing) base.Dispo

4、se(disposing); /必须调用基类的Dispose方法 /释放资源 ,Component类的Dispose方法 public void Dispose() Protected virtual Dispose( bool disposing ) 在组件直接或间接从Component类派生时,使用自定义方法覆盖基类的带参Dispose方法即可,但一定要在方法中实现调用基类的Dispose方法。 如果通过IDisposable接口来创建组件,需要自定义Dispose方法。,容器Container 实现了System.ComponentModel.IContainer接口的类,或者是从实现了

5、这个接口的类得到的派生类。 一个容器可以包含一个或多个组件,这些组件称为容器的子组件。 站点Site 实现了System.ComponentModel.ISite接口的类。或是由实现了这个接口的类得到的派生类。 由容器提供,以管理它所包含的子站点并与子站点通信。 子组件通过站点与容器进行交互。 容器和站点通常是作为整体来实现。,控件 具有用户界面的组件。 Windows窗体控件 从现有控件类派生的控件 从UserControl类派生的控件 从Control类派生的控件 组件通常以.DLL形式文件打包成程序集。其中包含了使用组件需要的所有信息,因此不需要再使用其他文件。 使用模板创建组件,其自动

6、配置项目属性可以生成DLL文件。,在组件中使用事件,触发事件的对象称作发送者,捕获并响应事件的对象称为接收者。事件是组件同客户进行通信的有效手段。 委托 事件通信中,事件的发送者不知道其接收者,我们需要一个媒介来连接发送者和接收者。这个媒介就是委托。 委托是一个类,用于绑定和引用方法。它具有签名,只能绑定匹配参数格式一致的方法。 public delegate void AlarmEventHandler( object sender, AlarmEventArgs e ); .NET框架中事件代理具有两个参数:事件源,触发事件的对象;事件参数,包含与事件相关的数据。 一般情况下,事件通常不产

7、生数据,可以直接使用.NET框架提供的System.EventHandler事件委托;当事件要产生一些事件数据时,就需要使用自定义的事件委托。,在类中触发事件,要在类中触发事件,前提条件有三: 事件参数类。从System.EventArgs类派生,如果事件不产生数据则可以直接使用这个类。如, public class AlarmEventArgs :System.EventArgs /事件字段,属性,方法等定义 事件委托。同样的,如果不产生数据,则可以直接使用System.EventHandler。否则要自己声明委托类型。如, public delegate void AlarmEventHa

8、ndler( object sender, AlarmEventArgs e); 触发事件的类。类中要包含事件声明以及触发事件的方法。如,,public class AlarmClock /声明事件Alarm,类型为AlarmHandler public event AlarmHandler Alarm; /声明触发事件的方法OnAlarm protected virtual void OnAlarm (AlarmEventArgs e) if(Alarm != null) /调用委托,它会相应地调用它所绑定的方法 Alarm(this, e); 示例程序,开发Windows窗体控件,Wind

9、ows窗体控件都直接或间接地继承自System.Windows.Forms.Control类,而这个类又继承自System.ComponentModel.Component类。它们都是组件。(如图) 创建开发Windows窗体控件方法(3种) 把已有控件组合到一起构成一个新控件。 这需要从UserControl类派生自己的控件类。VS2005中为这种控件提供了图形化的设计环境。这是个容器控件,当需要把多个窗体控件功能组合在一起的时候,这个方式很有用。,窗体控件继承体系(返回),从现有控件类派生新的控件。 这时要先选择一个特定的现有控件类,然后通过添加属性和方法等来扩充功能。当创建的控件功能与现

10、有控件功能基本相同时,采用这种方式。 不需要自定义图形接口,现有控件已经实现了。也可通过重定义基类的OnPaint方法实现。 创建一个控件。 从Control类派生自己的控件类,然后添加所需要的功能。Control类中定义了窗体控件最基本的功能,派生类都可以继承使用,不过没有提供绘制控件的方法,因此必须添加代码。 这种方式较复杂,但可以对控件进行充分定制。在不能从现有控件继承功能或是希望自行实现控件外观时,采用这种方式。,创建控件,创建控件前需要考虑的三个因素,然后再确定创建何种类型的控件。 控件是否需要自定义的图形化接口? 是否可以从现有控件中继承所需要的功能? 是否可以把多个控件结合在一起

11、来实现所需要的功能? 创建用户控件 直接使用VS2005提供的【Windows控件库】模板来创建。 【文件】|【新建】|【项目】【新建项目】对话框 选择Visual C#项目类型,【Windows控件库】模板,输入名称及保存位置。 然后在窗体设计器中会打开新创建的控件。用户控件的设计过程与窗体的设计过程基本相同。,也可以使用【用户控件】模板来创建。 【项目】|【添加用户控件】【添加新项】对话框。 在模板列表中选择【用户控件】选项。 这里也可以选择【继承的用户控件】选项,这将从自定义的用户控件中派生新的控件。 用户控件最后生成得到的是一个.DLL文件而不是.EXE可执行程序。项目生成后,可以通过

12、【工具箱】面板调用创建的用户控件。 创建自定义控件 这里包括从现有控件类派生或者从Control类派生新的控件,在VS2005中没有为这个方式提供项目模板。可以使用【Windows控件库】模板新建一个项目,然后修改自动生成的类代码,将自定义控件的基类改为摸个现有控件类。如,,public partical class UserControl1 :UserControl 改为 public partial class MyControl : Button 这里修改了自定义控件的类名,同时也要修改其构造函数的名称。如果通过属性窗口来修改类名的话,则构造函数名称会自动改变。 也可以在通过模板创建控件

13、项目后,使用【项目】|【添加新项】打开对话框,在模板中选择【自定义控件】选项来新建。 这种方式创建的自定义控件是从Control类派生的,在自动生成的代码中只提供一个空的构造函数和一个OnPaint方法(这个方法中只调用了基类的OnPaint方法)。 可以把基类改为任一现有控件,参照用户控件的代码来添加控件的初始化代码和Dispose方法。 在项目中添加了自定义控件后,可以将之前通过模板创建的用户控件类从项目中删除。 通常自定义控件中不包含其他控件。,添加控件属性、方法和事件,利用新建控件来实现所需功能,需要添加控件属性、方法和事件。这都通过手动添加代码。 看个例子,一个用户控件包含一个按钮控

14、件。现在要为这个用户控件添加一个属性,来获取或设置按钮的背景颜色(按钮为用户控件的私有字段,不能直接访问)。 public Color ButtonColor get return myButton.BackColor; set myButton.BackColor = value; 用户控件的方法使用与常规类完全一样,可以重写基类的方法,也可以使用重载。 可以直接使用基类定义的事件,通过重写基类的OnEventName方法(如OnPaint、OnMove等)来实现。,如果必须自定义事件,则需要做几件事情: 在控件类的定义中添加事件成员的声明; 选择一种合适的委托类型或者自定义代码类型和事件参

15、数类; 在控件类的定义中添加触发事件的方法。 如下例子 / 声明事件成员,使用的委托类型为System.EventHandler public event EventHandler ValueChanged; / 定义触发事件的方法 protected virtual void OnValueChanged(EventArgs e) if(ValueChanged != null) ValueChanged(this, e); /通过委托调用绑定的方法 ,控件的绘制,只有从Control类派生的自定义控件,用户才必须自己实现控件的绘制。从UserControl类或者是现有控件派生的控件类,可以

16、直接使用基类的OnPaint方法,也可以重写基类的这个方法来实现自定义的绘制功能。 一段示例代码 Protected override void OnPaint(PaintEventArgs pe) /调用基类OnPaint方法 base.OnPaint(pe); Pen myPen = new Pen(Color.Aqua); /使用剪裁区域绘制矩形 pe.Graphics.DrawRectangle(myPen, pe.ClipRectangle); ,OnPaint方法使用一个PaintEventArgs类型的参数,可以通过这个参数获取用于图形绘制的Graphics对象,然后使用它的各种

17、绘图方法来执行具体的绘图操作。此外,在这个参数中还包含一个ClipRectangle对象,表示绘图的矩形区域,只能在这个区域中进行图形绘制。 Control类实现的OnPaint方法中,只调用了绑定到事件委托的处理方法,而没有其他任何实际的绘图操作,所以其派生类调用基类的这个方法只是为了绑定到绘图事件委托上的处理方法能被调用。 为从UserControl类或现有控件类派生的控件实现绘图代码时,如果希望能完全的自定义绘图的过程和外观,则不要区调用基类的OnPaint方法。一般情况下,调用Invalidate方法来重绘控件,而不直接调用OnPaint方法。,每次调整控件大小时都会调用OnPaint

18、方法,而这时ClipRectangle只反映变化的部分,所以可能会出错。需要设置控件的ResizeRedraw属性为True,以避免发生这样的情况。可以在控件的构造函数中添加设置语句。如,ResizeRedraw = True; Control类中还有一个OnPaintBackground方法,用来绘制控件的背景。 它的参数与OnPaint方法一样,可以在这个方法中专门进行控件背景的绘制。 重写这个方法时,不需要调用基类的OnPaintBackground方法。 一般用户控件的绘制方法OnPaint都是个protected方法,无法直接调用。可以通过为这些控件的Paint事件添加处理方法来控制

19、这些控件的绘制。例如,,/绑定事件处理方法 this.myButton.Paint += new PaintEventHandler(this.MuPaint); /用户控件中的按钮的Paint事件的处理方法 proctected void MyPaint(object sender, PaintEventArgs e) /在这里添加相应的绘图代码 一些窗体控件(如TextBox等)的绘制由Windows系统直接完成,它们的OnPaint方法永远不会被调用,并且不能为它们的Paint事件添加处理方法。,控件的设计时支持,可以在控件的设计时使用一些辅助功能: 添加一个在【属性】窗口中显示的简要描

20、述信息 为控件创建自定义的属性、设置方式和显示外观等 还可以创建相应的HTML帮助等等。 使用Attribute为控件添加描述信息 .NET的窗体设计器中使用【属性】窗口在设置属性时会提供简要的属性描述信息,对于用户创建的控件,也可以提供这种功能:通过为控件添加相应的Attribute来实现。 如Description特性为控件的成员(属性和事件)添加简要的描述信息;Browsable特性指定某个属性是否会出现在【属性】窗口中等等。 DescriptionAttribute特性类在命名空间System.ComponentModel中定义,所以使用前要用using导入。,常用的设计时属性,示例代

21、码,using System.ComponentModel; Description(“控件的简要描述信息”) DefaultProperty(“MyProperty”) /指定控件的默认属性 DefaultEvent(“ValueChanged”) /指定控件的默认事件 public class MyControl : Control /下面这个属性将会在【属性】窗口中显示 Browsable(True) DefaultValue(0) /指定属性的默认值 Localizable(True) /该属性将会被本地化,保存在资源文件中 public int MyProperty get set

22、/下面这个属性不出现在【属性】窗口中 Browsable(False) public int ServingSize /指定下面这个属性的类别和描述信息 Category(“外观”), Description(“指定文本的对齐方式”) public ContentAlignment TextAlignment public event EventHandlerValueChanged; /声明一个事件 ,为自定义类型的属性创建类型转换器 添加控件的属性,有时需要指定它为自定义的类型。为了使用窗体设计器能把其他类型的值转换成自定义的类型或是从自定义类型转换成其他类型,需要提供一个类型转换器。 从

23、System.ComponentModel.TypeConverter类派生创建转换器类,重写基类的几个方法就可以完成所需的类型转换器的实现。 一个实现从自定义的Point类型到string类型的转换器PointConverter的示例。 实现了自定义的类型转换器后,就可以在相应的属性上使用TypeConverter特性为这个属性指定类型转换器。如, TypeConverter (typeof(PointConverter) Public Point Location get set ,为属性指定UI类型编辑器 使用【属性】窗口设置控件属性时对于不同类型的属性,可以有不同的设置方式。 有的可以

24、直接输入,有的通过下拉列表选择,有的会显示一个对话框进行设置等。这种功能通过UI类型编辑器来实现。 几个预定义的类型编辑器 ArrayEditor,用于编辑数组属性 ListItemsCollectionEditor,用于编辑列表项 FontEditor,用于编辑字体属性 ImageEditor,用于编辑图像属性 FileNameEditor,用于编辑文件名 FolderNameEditor,用于编辑文件夹名,使用Editor特性来为控件的属性指定其对应的类型编辑器,这样就可以在【属性】窗口中以合适的形式来编辑属性值,如, Category(“外观”), Description(“指定字体”)

25、, Editor(typeof(FontEditor), typeof(UITypeEditor) public Font MyFont 设计时使用的类型编辑器都位于命名空间System.Drawing.Design中,在程序集System.Drawing.Design.dll中实现。 可以为自定义的属性类型实现一个自定义的类型编辑器。 从System.Drawing.Design.UITypeEditor中派生自己的新类, 然后重写基类的EditValue方法以设置用户界面 重写基类的GetEditStyle方法向【属性】窗口返回适当的信息,ErrorProvider组件,用于验证窗体或控件上的用户输入是否合法 当验证用户在窗体或控件中的输入或显示数据集内的错误时,使用这个组件相对于使用消息框来显示错误信息会是一个更好的选择。因为消息框一旦关闭,错误信息就没有了。 这个组件会在出错的相关控件旁显示一个错误图标(一个带“!”的红色圆圈);把鼠标放在这个图标上时将显示错误信息。 主要属性与方法 DataSource,设置要显示错误信息的数据集。 ContainerControl,设置包含这个组件的窗体或容器控件。 Icon,设置错误显示图标。 SetError方法,指定错误信息字符串并指定图标显示的位置。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1