.Net开发笔记(七)使用组件编程

本文主要说到以下内容:

  • 什么是.Net中的组件,组件和类、控件的区别和联系。
  • 组件的特性。
  • 利用IExtenderProvider接口进行组件扩展。
  • “扩展组件”的简单应用——控件倒影。

1. 什么是.Net中的组件,组件和类、控件的区别和联系

必须说的是,“组件”一词在编程中经常遇到,意义众多,当然不管什么意思,从字面上来看就知道它应该有“一个可重复使用的单元”的意思。在.Net中,“组件”就特指实现了System.ComponentModel.IComponent接口的类,或者从实现了该接口的类直接或间接派生的子类。因此,“组件”它属于“类”,满足一定标准的类就是组件,而这个标准就由IComponent接口提供。那么什么是控件?组件跟控件有什么关系?我们知道,所有的控件都从System.Windows.Forms.Control类直接或间接派生(Asp.Net中从System.Web.UI.Control),而再查看System.Windows.Forms.Control源码我们会发现,它继承自System.ComponentModel.Component类,后者又实现了System.ComponentModel.IComponent接口,因此,我们可以说,控件也是一种组件。

综上,我们可以得出结论:

  • 类包含组件,组件包含控件。
  • 类不一定是组件,但组件一定是类,组件不一定是控件,但控件一定是组件。
  • 不管是类、组件还是控件,它们都是“一个可重复使用的代码单元”。
  • 不管是类、组件还是控件,他们都应该符合OO编程规律。

举一个FCL中的例子,来说明问题:

  • System.Windows.Forms.Application是一个类,既不是组件也不是控件。
  • System.Windows.Forms.Timer是一个类,也是一个组件,但不是控件(注意)。
  • System.Windows.Forms.ToolTip是一个类,也是一个扩展组件(后面说明什么是扩展组件),但不是控件。
  • System.Windows.Forms.Button是一个类,也是一个组件,同时也是控件。

上一张图说明关系:

.Net开发笔记(七)使用组件编程

图1

2. 组件的特性

1)假设各位知道Dispose模式,Dispose模式一般用于对象中使用了资源(包括托管资源和非托管资源)的场合,具体就是让定义的类实现IDisposable接口。查看System.ComponentModel.IComponent源码会发现,它实现了IDisposable接口,因此,可以说,所有的组件都具备有效管理资源的特性。

2)如果各位使用VS开发工具,那么,凡是实现了System.ComponentModel.IComponent接口的类,即凡是组件者,都可以将它添加在ToolBox中(工具箱),也就是常说的“可视化支持”。

3)Winfrom开发过程中,在设计窗体时,查看Form1.Desinger.cs文件,Form1类中有private System.ComponentModel.IContainer components数据成员,查看InitializeComponent()方法中会发现,一切类似Timer、ImageList、ToolTip这样的组件在构造时,都会像下面这样:

   this.imageList1 = new System.Windows.Forms.ImageList(this.components);

其中System.ComponentModel.IContainer字面意思可以看出它是一个容器,也就是说,每个组件在自我构造的时候,都会把自己加到一个容器中去。事实上,组件一般都不会单独去使用,都是由容器去管理,容器生命期结束时,容器中的各个组件也会结束自己生命期。

注:容器包含组件只是逻辑包含,跟通常的List、Array等集合包含元素不同。

有关IDE对组件的可视化支持,以及容器与组件之间的详细关系是一个非常复杂的话题,本文暂时不涉及。

3. 利用IExtenderProvider接口进行组件扩展

通常当使用一个组件时,需要在原有的基础上添加新的功能,也就是说需要扩展原有功能,我们做不到修改原有组件的代码,比如我们需要一个圆角按钮,现有的标准按钮(System.Windows.Forms.Button,前面说过它属于组件)是直角,第一想到的办法就是新建一个ButtonEx类继承Button,建立一个新的扩展控件。

以上是一种办法,但当需要给一类组件增加新的功能时,使用以上方法就会导致出现许多的扩展控件,而且有些时候只是新增加一个小功能,并不需要产生新的控件,因此,这时候有必要看看System.ComponentModel.IExtenderProvider这个接口。关于这个接口,我就不引用MSDN上的定义了,描述得太抽象,基本没什么参考价值,我将该接口的功能描述如下:

当需要为其它某个(或某些)组件扩展新的功能,又不能做到直接修改原有组件的源代码时,我们就可以定义一个类,让其实现IExtenderProvider接口。

IExtenderProvider接口源码如下:

.Net开发笔记(七)使用组件编程View Code

FCL中已有的例子有很多,前面提到过的ToolTip就属于这种,查看System.Windows.Forms.ToolTip源码会发现,它继承自System.ComponentModel.Component,并且实现了System.ComponentModel.IExtenderProvider接口,大概源码如下:(模仿,非实际)

.Net开发笔记(七)使用组件编程View Code

解释:[ProvideProperty(“ToolTip”,typeof(Control))]的意思是给所有的Control类及其派生类增加属性“ToolTip”,也就是说原来的标准控件Button现在应该增加了ToolTip属性,在界面设计器中,从工具栏中拖出一个ToolTip组件,那么所有的其他控件在属性栏中增加了一项“toolTip1 上的 ToolTip”,可以设置该新增的属性,比如我给按钮button1设置该属性“it’s a button”,那么设计器生成的代码就是toolTip1.SetToolTip(button1,”it’s a button”);。

注:以上GetToolTip(Control control)和SetToolTip(Control control,string caption)方法具体实现暂没说明,不同情况实现不一样,具体可以参考下面的“控件倒影”demo代码。

4.“扩展组件”的简单应用——控件倒影。

让每一个标准控件都具有倒影效果,这一要求完全符合IExtenderProvider接口的使用范围,第一,需要给组件扩展新的功能;第二,数量之多,单单通过继承创建新的扩展控件麻烦;第三,新加功能很小,只是增加一个倒影效果。先上一张效果图:

.Net开发笔记(七)使用组件编程

图2

为了让任何一个控件都具有“倒影效果”,可以给每个控件扩展一个HasMirror的属性,数据类型为Bool型,另外,需要创建一个倒影类,负责显示倒影。

扩展类:

.Net开发笔记(七)使用组件编程View Code

倒影类:

.Net开发笔记(七)使用组件编程View Code

测试时,从工具箱中拖放一个MirrorExtender组件,窗体设计器中各个控件就会增加一个“mirrorExtender1 上的 HasMirror”属性,设置为true,该控件具有倒影效果,反之,则没有倒影效果。

.Net开发笔记(七)使用组件编程

图3

希望对各位有帮助,O(∩_∩)O~

作者:周见智 
出处:http://www.cnblogs.com/xiaozhi_5638/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类: .NET Framework
标签: c#

本文转自周见智博客博客园博客,原文链接:http://www.cnblogs.com/xiaozhi_5638/archive/2013/03/01/2939209.html,如需转载请自行联系原作者
上一篇:冬季实战营第四期:零基础容器技术实战笔记


下一篇:.Net开发笔记(十四) 基于“泵”的UDP通信(接上篇)