Farseer

导航

用户控件(User Control)

为了提高代码的复用性,特别是页面设计代码(指Html代码)的复用性,Asp.net提供了两种定义控件的方式,一种是用户控件(User Control),一种是定制控件(Custom Control)。两者的区别很简单,用户控件类似于设计好的页面,而定制控件则会生成dll,这样定制控件可以向Web Control一样出现在工具箱里通过托放拖到用户的设计页面,而用户控件必须手动在页面的Html页面添加(当然也可以在项目浏览器(Solution Explorer)中直接拖到页面上,但这必须是页面包含在项目中)。由于用户控件可以看作是控件的聚合,而定制控件是控件的继承和扩展,用户控件可以方便地进行页面设计,所以大多数情况下我们采用了这种方式。

至于为什么要用用户控件,如何制作用户控件,用户控件是如何工作的,我还是通过翻译的一篇文章来阐述。因为我看了这篇文章后发现我知道的都在里面,我不知道的也在里面。

我也明白了一个真理,微软的东西如果想获得最直接,全面的了解,要从MSDN的英文帮助上找,因为我发现几乎所有的知识点,在搜索了所以的中文相关描述后,发现链接指向了同一篇MSDN的英文帮助.MSDN上的描述是最全面和最直接的,看英文也是蛮累的,这也就是为什么印度的软件比中国发达的根本原因.当然如果不想深究(大多数情况下深究并没有必要),直接看看论坛给出的结果也就可以了.

老外的文章很规范,完全围绕着Why,How,What的思路进行.首先阐述为什么要相关的技术,接着阐述如何实现,最后介绍实现的机理.中国人写的文章要么取其一,要么取其二,很少有人详细地阐述清楚.

我翻译的这篇文章也秉承了这样的思路,不过完整地翻译一篇文章实在太浪费时间,我把读后的认识按照作者的思路陈述如下:

为什么要用户控件?
1.节约了开发时间,控件到处可用.
2.较低了bug的重现
3.便于bug的修改

如何制作用户控件?
基本的知识地球人都知道了,说几个我在中文帮助上没见过的.
1.可以通过将控件从Solution Explorer上拖到设计页面的方式添加用户控件.
2.用户控件的路径问题,还记得../../../这样的方式吗?鬼晓得当前页在项目文件的第几层啊,微软早就给出了解决方案,~/代表项目文件的根目录.
其他的诸如如何添加事件,如何响应事件,这些大家都知道了,就不再累述了.

为什么可以实现?

正如大家都知道的,Html页面是Code-behind中类的子类,html代码第一次生成或者任何修改,html代码都会重新编译,而Asp.net真正实例化的对象是html页面的子类。这就是为什么在页面上添加一个控件后,CS文件里不用重新用new来生成对象,而不会报告“未将对象引用设置到对象的实例中”的原因吧,因为html代码在添加一个控件的同时也就实例化了一个控件(相当于在其父类中用new生成该控件).

正因为如此,html代码的控件树可以如下展示:



可以看出<html><body>等都是Html标志都是LiteralControl的实例。而包含在<form>中的内容就是<HtmlForm>的实例了。

当页面的层次建立好以后,Asp.net的Web页面就可以依次调用Web控件的RenderControl(HtmlTextWriter)方法来呈现自己。当控件的RenderControl(HtmlTextWriter)方法被触发时,控件会生成Html代码,并附加到HtmlTextWriter对象中。每次页面被请求时,上述过程都会发生一次。

下面是用户控件的层次:



可以看出用户控件的层次跟Page类似,只是继承自UserControl。

下图是页面中包含了用户控件后的层次结构


当用户控件被加入到页面的控件层次的时候,InitializeAsUserControl(Page)方法被调用,这个方法在System.Web.UI.UserControl类中,用户控件的html代码继承自Code-behind代码,而Code-behind继承自System.Web.UI.UserContorl,所以用户控件间接继承自System.Web.UI.UserControl.这个方法创建控件的层次结构,并将用户控件的Page属性赋值,这样在用户控件中就可以引用其所属的页面实例了.

一旦用户控件被附加到页面的控件层次并创建后自己的控件层次后,页面的层次控件就像没有采用用户控件而是直接将html代码嵌入到页面的html代码部分一样.然后页面会一次调用每个空间的RenderControl(HtmlTextWriter) 方法,呈现页面.

好了,就这些了.








posted on 2005-04-04 09:38  佛西亚  阅读(1719)  评论(1编辑  收藏  举报