1 / 35

组件开发的经验和思想

组件开发的经验和思想. 青岛微软开发者俱乐部 张磊 (xiaopang). 组件开发中的几点经验. 接口在组件开发中的使用 使用组件来完成简单但繁琐的处理 给二次开发提供方便 使用可视化界面进行组件的属性设置 System.Windows.Forms.ControlPaint 组件功能最大化,可通过开关属性控制 组件形成系列化,易于协作. 有时候我们为了处理方便,或者为了让现在的组件能和将来用户自定义的组件进行通讯,我们可以采用接口的方式来处理,下面通过几个例子来说明一下. 接口在组件开发中的使用.

bree
Download Presentation

组件开发的经验和思想

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 组件开发的经验和思想 青岛微软开发者俱乐部 张磊(xiaopang)

  2. 组件开发中的几点经验 • 接口在组件开发中的使用 • 使用组件来完成简单但繁琐的处理 • 给二次开发提供方便 • 使用可视化界面进行组件的属性设置 • System.Windows.Forms.ControlPaint • 组件功能最大化,可通过开关属性控制 • 组件形成系列化,易于协作

  3. 有时候我们为了处理方便,或者为了让现在的组件能和将来用户自定义的组件进行通讯,我们可以采用接口的方式来处理,下面通过几个例子来说明一下有时候我们为了处理方便,或者为了让现在的组件能和将来用户自定义的组件进行通讯,我们可以采用接口的方式来处理,下面通过几个例子来说明一下 接口在组件开发中的使用

  4. 比如,如果我们想让我们的系统以资源的方式支持多国语言,就可以给每一个可视化组件加上资源ID和资源类型的属性,如下图 对于那些需要显示文本的控件(当然,那些显示图片、播放声音等的控件也可以采用类似的方法),如label、button、form等等,都需要这两个属性。因此,我们可以定义一个接口来表示这两个属性:

  5. 下面是一个自定义的Label类的部分代码,它实现了上面的资源接口下面是一个自定义的Label类的部分代码,它实现了上面的资源接口

  6. 可视化控件总是放到某个容器上的,要想实现国际化的版本,就需要这些容器来完成可视化控件总是放到某个容器上的,要想实现国际化的版本,就需要这些容器来完成 国际化界面的显示。因为容器很多,所以我们让这些容器也实现一个显示自己子控件 国际化属性的接口: 对于实现了这个接口的容器控件,我们可以通过调用ShowChildByResource 方法来让它的子控件显示国际化的界面。 下面是一些容器类(如Form,GroupBox,Panel等)显示国际化界面的代码

  7. 注释部分

  8. 代码部分

  9. 上面这段代码有比较长的一段注释,这些注释也是编写组件很重要的一部分,它说明了这个方法的用法,并给出了一个示例,我们也可以根据这些注释来自动生成和vs.net里基本一样的帮助文件来,这个工具叫NDoc,我做了一些汉化,可以在下面这个网址找到下载(下图是生成的帮助文件截图):上面这段代码有比较长的一段注释,这些注释也是编写组件很重要的一部分,它说明了这个方法的用法,并给出了一个示例,我们也可以根据这些注释来自动生成和vs.net里基本一样的帮助文件来,这个工具叫NDoc,我做了一些汉化,可以在下面这个网址找到下载(下图是生成的帮助文件截图): http://blog.csdn.net/tashanzhishi/archive/2005/08/20/459485.aspx

  10. 例如,我们设计了一个组件GStandKey,它的某一个功能是可以显示查询窗口,并且返回用户在查询窗口选定的数据集合;根据这个要求我们可以设计出一个和它交互的数据查询窗口控件来,该控件运行界面如图:例如,我们设计了一个组件GStandKey,它的某一个功能是可以显示查询窗口,并且返回用户在查询窗口选定的数据集合;根据这个要求我们可以设计出一个和它交互的数据查询窗口控件来,该控件运行界面如图: • 接口更重要的作用还不是这个,而是在组件的互操作性方面,我们也通过简单的示例来说明 当然,这个控件功能很多,支持时间查询,也支持多列,这个控件能够完成我们大部分查询要求。不过,实际业务逻辑是复杂的,在一些特殊的情况下,这个界面可能就不能满足我们的要求了。那么怎么办呢?我想可以使用接口来解决这个问题。我们可以把需要和这个窗口交互的东西都以接口的形式公开出来,任何实现了这个接口的窗口都可以和GStandKey组件进行通讯。这个接口我们可以这样设计:

  11. 这样以来,不管将来的查询窗口怎样设计,也不管具体的业务逻辑如何,只要这些窗口实现了这个接口,我们就可以在这些组件里使用将来的查询窗口了

  12. 使用组件来完成简单但繁琐的处理 在软件开发中,有一些工作虽然简单,但因为这些工作量很大,需要重复做很多次,比较耗费时间。对于这样的情况,我们可以使用组件来简化我们的工作,下面也通过示例说明

  13. 在.net里进行数据绑定虽然比较简单,但如果要处理的数据字段比较多的话,或者一个数据集有多个数据表的话,进行绑定还是有些繁琐的;特别是用代码来一个个实现绑定的话,代码量就更大了。但这些东西我们都可以使用一个专门用来绑定的组件来完成。我们让所有可能需要绑定数据的控件都实现一个接口,这个接口记录了该控件需要绑定到的数据对象,如下所示 : 数据绑定组件要做的工作就是,把给定的窗体上需要帮定的控件都绑定到指定的数据集上 ,代码如下:

  14. 这样就可以很容易的完成数据的绑定,你要做的工作只是给组件的DataMember属性赋上值即可,如图:这样就可以很容易的完成数据的绑定,你要做的工作只是给组件的DataMember属性赋上值即可,如图: 这里CustomTableInfo表示数据集中的表名DefinedTime表示字段名。 还有一个例子,是这样的,我们经常需要在我们的软件里加上配置功能,可能这些信息是用户的操作习惯,也可能是数据库连接信息,或者是别的其它信息。这些配置功能用途很广,操作起来也不太麻烦,但如果这些配置多了,也是需要不少工作量的。在这种情况下,我们也可以使用组件来完成,假设我们要实现如右图所示的配置窗口:

  15. 我们就可以这样来设计属性 : 我们把每一个配置的相关信息设计好,具体的界面显示和数据存储都可以交给系统来完成,这样即避免了编写代码可能带来的错误和工作量,又可以保持界面的高度一致性,还是值得去做的。

  16. 给二次开发提供方便 组件的一个显著的特点就是比较容易定制自己的方法和事件,特别是事件,有很广泛的应用。在这里我和大家探讨一种处理不确定业务逻辑的方法 :

  17. 如下图,这是一个增强的datagrid的截图 它的品号列是一个比较特殊的列,列的类型是PopFormColumn,也就是可以通过点击旁边的按钮来弹出一个窗口,如图:

  18. 但有些时候我们不一定是让它弹出这个窗口,我们可能在用户点击这个按钮时发送一封邮件,也可能是别的不能在设计组件时就考虑到的操作。这个时候我们就可以使用事件来完成;但有些时候我们不一定是让它弹出这个窗口,我们可能在用户点击这个按钮时发送一封邮件,也可能是别的不能在设计组件时就考虑到的操作。这个时候我们就可以使用事件来完成; 比如我们给那个增强的grid定义一个新的事件,叫OnCreatePopColumns,它返回一个PopFormColumn对象。在grid创建弹出窗口列的时候触发;如果没有事件处理程序的话,它自己创建默认的弹出窗口列,否则就把返回的对象作为本来它应该创建的对象。这样,程序员在设计OnCreatePopColumns的事件处理程序时,就可以根据实际业务情况,从PopFormColumn继承出自己需要的对象,并做相应的处理。 这里面的关键点是:我们的组件自己能够处理大部分可以预见的业务情况,只对那些不可遇见的业务情况才需要设计事件处理程序,这样,即使业务逻辑在我们的预料之外,我们还是可以使用我们组件提供的很多功能。 除了返回这些业务逻辑相关对象以外,通过事件返回数据集也是一个很有意思的地方,它也适用在和这个类似的情况下。 总之,使用这种方法,可以解决很多不确定业务逻辑的情况,使组件的使用范围大大拓展。

  19. 使用可视化界面进行组件的属性设置 在我们开发的组件中,有相当一部分的属性设置是很复杂的,但如果使用写代码的方法来设计属性的话,可能就简单一些;不过,我还是不推荐使用代码的方式来设置属性,我认为最好的方法还是通过可视化的属性编辑器来进行属性设置 。 我们下面也通过一个例子来探讨一下:

  20. 例如,有这样一个窗口 大家可以想一下,如果通过代码来写的话,需要多少代码才可以设计出这样一个窗口呢? 但如果使用可视化属性设置的话,只需要几分钟时间就可以设计好了。 下图是那个组件的属性设置界面:

  21. 这样,通过这些属性设置就设计出了上面运行界面中的查询窗口。这样,通过这些属性设置就设计出了上面运行界面中的查询窗口。 我们可以看到,使用可视化属性设计界面可以大量节省程序员的代码量,并且提供高度一致的运行界面,也大大降低了程序设计的难度,使我们可以把更多的精力投入到业务逻辑的处理上去。当然,设计可视化属性设计器也是有一定的难度的,关于这方面的详细情况我们可以以后再讨论,重要的是使用这种思想

  22. System.Windows.Forms.ControlPaint 这个是一个非常简单的技巧,虽然我们平时几乎不用,但在组件设计中,用处还是蛮多的。这个命名空间提供了绝大部分windows控件绘制的方法,基本上我们常见的windows控件全可以用它非常简单的绘制出来,具体细节大家看一下帮助就明白了,这里只是简单提起一下而已

  23. 组件功能最大化,可通过开关属性控制 组件最重要的特点就是重用,因此我们设计组件时,要好好规划一下组件需要完成的功能,把可以在一个组件中完成的功能尽量都集中起来。当然,有些功能在某些情况下是没有用的,这个时候我们应该能够根据实际情况来屏蔽这些功能。一个比较常用的方法是这样的,就是在这个组件里完成一个最大功能集合,然后使用一些属性来作为这些功能的开关

  24. 给大家举一个例子,如下图 这个网格控件是从System.Windows.Forms.DataGrid继承过来的,在大家通常的感觉中,DataGrid控件不好用,功能不强;但是,如果我们把这个DataGrid增强一下功能的话,还是很好用的。在这里我们给它增加了很多功能 :

  25. 行序号显示 • 可以通过右键菜单选择要显示的列 • 支持列拖放 • 各种列类型(下拉列表、选择框、时间选择、弹出窗口等等很多)的支持 • 自动记录列宽、列顺序、某列是否显示等信息 • 自动生成关联查找窗口 • 末列宽度自动调整 • … 当然,还提供了很多事件可以处理,通过这些事件可以更精确的控制网格,比如我们就可以处理某一个网格的双击事件。

  26. 通过这些功能增强,使组件的适用范围扩大了很多,当然有些时候我们可能不需要某些功能,比如我们可能不需要调节列的顺序或者不需要记录列的信息,我们就可以通过几个布尔型的属性来控制这些功能的开关。这样,我们常用的一些需求基本也就可以满足了,而通过属性的控制,可以让组件更贴近我们的需求 上面是对一个组件进行功能增强的情况,还有一种情况,就是多个组件组合成更强功能组件的情况,具体来说就是把许多功能相关的组件组合成一个大组件,并且为这些子组件提供默认的处理程序,如图

  27. 上图是一个组件,它包括了数据操作的常用按钮,并且对每一个按钮都内置了默认操作方法。我们在不写任何程序的情况下,就可以对默认关联的数据集完成新增、删除、查找、打印、关闭窗口等操作。即使对与保存,我们也只需要写很少的几行代码就可以完成。当然,对与每一个按钮我们都预留了事件处理接口,可以自己写程序处理这些事件。由于一些窗口可能不需要打印、属性、自定义这些按钮,我们也可以通过属性设置来屏蔽或隐藏这些按钮,如下图 这是把多个组件组合成一个功能增强的组件,并可以通过属性控制的情况,我们更多的时候处理的就是这种情况。

  28. 组件形成系列化,易于协作 在软件开发中,如果仅仅为了业务需要只开发出几个组件,那么这些组件带来的好处也很有限,更好的进行快速开发的方法是让组件形成系列,通过多个组件进行协作,共同完成一个复杂的业务过程

  29. 下图是一个简单的主从表窗体的例子,大家可以看到里面用到了很多组件,而这些所有的组件全是我们自己设计的,也就是说没有一个组件是标准的.net组件:下图是一个简单的主从表窗体的例子,大家可以看到里面用到了很多组件,而这些所有的组件全是我们自己设计的,也就是说没有一个组件是标准的.net组件:

  30. 这是程序运行界面

  31. 我们可以看一下这些组件是怎么配合的: 很显然,窗体最上部那些组件是用来显示主表数据的,中间的是用来显示明细数据的,最下面的数据主控组件是用来控制处理数据的,还有两个查找窗口组件,是用来显示弹出的查找窗口的。 首先,那些需要和数据绑定的组件都实现了IDataMember接口;数据主控组件可以用来得到要处理的数据集,它本身还包括一个自动绑定组件,该组件可以把窗体上所有需要绑定的组件(该组件必须实现了IDataMember接口)都绑定到合适的数据集上去。数据主控组件还可以和查找窗口组件象配合,在需要查找数据时,让查找窗口组件完成查找窗体的界面显示,它本身则提供查找的数据。当然,在默认情况下,数据主控组件是和网格控件配合进行查找的,它从网格取出列信息,构造查找界面,并从自身的数据集中根据用户的要求进行查找。数据主控控件还和后台数据处理组件配合,把数据的更改传送到数据处理组件,让它自动完成数据的存储。 由此可见,要想真正提高组件式开发的效率的话,必须提供出一套互相紧密配合的组件,让这些组件本身进行自动交互。当然,开发出这套组件本身就是一个负责的工程,但当我们完成它后,就可以给我们的开发工作带来很大的便利。

  32. 交流方式 • 青岛微软开发者俱乐部(www.qddn.net) • blog(http://blog.csdn.net/tashanzhishi/) • msn(zl3624@hotmail.com)

More Related