第八章 生成
不要从控件里调用Page.Response.Write,此方法虽然会向HTTP响应流里写入内容,但是生成的内容可能会在页面生成控制树之前或之后出现,根据控件在页面层次中的位置,生成的内容可能不会在页面设计者期望的地方出现,并且这样做就打破了页面框架提供的封装,因此,在控件中实现rendering功能,必须重载Control类或WebControl类中提供的一个rendering方法。
Control类的rendering方法
·protected virtual new void Render ( System.Web.UI.HtmlTextWriter writer )
允许控件通过编写标记文本生成自身。当控件直接从Control类派生时,应该重载这个方法来生成所需内容。
·protected virtual new void RenderChildren ( System.Web.UI.HtmlTextWriter writer )
在HtmlTextWriter对象的流中生成控件的子控件。默认情况下,子控件按照它们加入控件的Control集合时的顺序生成。当需要改变子控件的默认逻辑时,要重载这个方法,比如,需要在两个子控件中插入一些其他文本,就要重载此方法。
·public void RenderControl ( System.Web.UI.HtmlTextWriter writer )
生成一个控件。Render方法的类型是受保护的,而RenderConrol的类型为公用的,它允许消费(使用)一个类能够生成控件,例如,当页面生成控件树时,在每个子控件上都要调用RenderControl方法。作为控件开发人员,需要在生成一个子控件时调用RenderControl方法。当控件的Visible属性为真时,则RenderControl实际是通过调用Render方法来实现的。
页面生成
页面也是一个控件(Page类是从Control类间接派生的),它也拥有和其他控件相同的生成能力,这就使页面有能力通过rendering方法将其本身或子控件输出。
每个页面都有一个控件树,代表本页面所拥有的所有子控件,而页面控件就是控件树的根。
页面生成逻辑(P121)
为了生成控件树,页面将建立一个HtmlTextWriter类的实例,在这个实例中封装响应流,接着页面将这个HtmlTextWriter对象传递给RenderControl方法,RenderControl方法检查控件的Visible属性是否为真,如果为真,RenderControl调用Render方法,Render方法的默认实现会调用RenderChildern方法,RenderChildren方法默认调用每个子控件的RenderControl方法。通过这种递归调用的方法就可以生成控件树。
从Control类派生控件时,可以重载Render方法来向响应流里写入标记文本。
使用HtmlTextWriter对象的标签和标签生成功能关联的HtmlTextWriterTag和HtmlTextWriterAttribute枚举类型能够简化代码、减少错误并使代码具有更好的可读性。
HtmlTextWriter:由System.IO.TextWriter派生,System.IO.TextWriter提供了向输出流中写入文本的功能。通过提供一种简化写入和格式化HTML标签和attribute的方法,HtmlTextWriter增加了基类的功能。
HtmlTextWriter相关枚举类型:HtmlTextWriterTag、HtmlTextWriterAttribute、HtmlTextWriterStyle
WebControl类的rendering方法
·protected virtual new void AddAttributesToRender ( System.Web.UI.HtmlTextWriter writer )
使Web控件指定名/值对,作为HTML元素标签的attribute提供。在重载AddAttributeToRender时,必须调用基类中相应的方法,否则控件将失去重要的功能。WebControl基类按照这种方式实现将会生成大量控件属性作为HTML attribute。
·public virtual new void RenderBeginTag ( System.Web.UI.HtmlTextWriter writer )
使Web控件在输出流中写一个开始标签,如果想对开始标签进行不同的处理,需要重载这个方法。如果控件只生成一个标签并想重载WebControl产生的默认<span>标签,应该重载TagKey或TagName属性。
·protected virtual new void RenderContents ( System.Web.UI.HtmlTextWriter writer )
使Web控件生成控件标签内的内容。默认情况下,本方法会生成子控件树。如果要在控件的标签中写入文本或其他内容,需要重载这个方法。如果要使用默认逻辑来产生子控件,需要调用基类的相应方法。
·public virtual new void RenderEndTag ( System.Web.UI.HtmlTextWriter writer )
使Web控件在输出流中写入一个结束标签。只有提供的结束标志匹配按照RenderBeginTag方法(如果在控件中重载此方法)创建的标签时,才需要重载此方法。
Web控件生成逻辑:
·在调用RenderBeginTag方法之前,必须提供标签的所有attribute和样式attribute,这是因为HtmlTextWriter对象在开始写标签的时候需要它们的attribute信息;
·需要分别单独调用AddStyleAttribute来传递每个样式attribute,HtmlTextWriter将所有的样式attribute合并到一个以分号分割的列表之中;
·每调用一次RenderBeginTag方法必须对应调用一次RenderEndTag方法,这同样适用于那些在HTML中没有对应的结束标记的标签,如<input>;
·name attribute为控件生成表单输入元素的唯一name,这样的元素才能参与到数据处理过程的回传中,标准ASP.NET表单控件将控件的UniqueID分配给name attribute,如果拥有多个表单元素,就必须基于控件UniqueID为每个元素创建不同的名字;
·id attribute用于客户端教本访问,每个元素中的id必须是唯一的,利用页面框架的ClientID属性来生成唯一的id attribute,默认情况下,WebControl生成ClientID属性作为HTML id。
低版本生成
HtmlTextWriter类有两个版本:HtmlTextWriter、Html32TextWriter
HtmlTextWriter:输出 HTML 4.0 代码
Html32TextWriter:派生自HtmlTextWriter,输出 HTML 3.2 代码
当页面收到一个Web请求时,它利用服务器的 HTTP_USER_AGENT 变量来检测浏览器的类型,并根据 web.config 文件的定义为得到的浏览器类型创建相应的 HtmlTextWriter。正确的 HtmlTextWriter 对象就是这样被自动传递给控件内的 rendering 方法。
前提:只有使用 HtmlTextWriterTag 枚举类型来生成标签,控件才能使用 HtmlTextWriter 对象提供的自动标签转换功能。
可以通过 Page 指令中的 ClientTarget attribute 指定目标浏览器,这个 attribute 将会重载自动浏览器检测,导致创建映射到该 attribute 值指定的浏览器的 HtmlTextWriter。
Control类的rendering方法
·protected virtual new void Render ( System.Web.UI.HtmlTextWriter writer )
允许控件通过编写标记文本生成自身。当控件直接从Control类派生时,应该重载这个方法来生成所需内容。
·protected virtual new void RenderChildren ( System.Web.UI.HtmlTextWriter writer )
在HtmlTextWriter对象的流中生成控件的子控件。默认情况下,子控件按照它们加入控件的Control集合时的顺序生成。当需要改变子控件的默认逻辑时,要重载这个方法,比如,需要在两个子控件中插入一些其他文本,就要重载此方法。
·public void RenderControl ( System.Web.UI.HtmlTextWriter writer )
生成一个控件。Render方法的类型是受保护的,而RenderConrol的类型为公用的,它允许消费(使用)一个类能够生成控件,例如,当页面生成控件树时,在每个子控件上都要调用RenderControl方法。作为控件开发人员,需要在生成一个子控件时调用RenderControl方法。当控件的Visible属性为真时,则RenderControl实际是通过调用Render方法来实现的。
页面生成
页面也是一个控件(Page类是从Control类间接派生的),它也拥有和其他控件相同的生成能力,这就使页面有能力通过rendering方法将其本身或子控件输出。
每个页面都有一个控件树,代表本页面所拥有的所有子控件,而页面控件就是控件树的根。
页面生成逻辑(P121)
为了生成控件树,页面将建立一个HtmlTextWriter类的实例,在这个实例中封装响应流,接着页面将这个HtmlTextWriter对象传递给RenderControl方法,RenderControl方法检查控件的Visible属性是否为真,如果为真,RenderControl调用Render方法,Render方法的默认实现会调用RenderChildern方法,RenderChildren方法默认调用每个子控件的RenderControl方法。通过这种递归调用的方法就可以生成控件树。
1 public void RenderControl (System.Web.UI.HtmlTextWriter writer)
2 {
3 if(Visible)
4 {
5 Render(writer);
6 }
7 }
8
9 protected virtual new void Render (System.Web.UI.HtmlTextWriter writer)
10 {
11 RenderChildren(writer);
12 }
13
14 protected virtual new void RenderChildren (System.Web.UI.HtmlTextWriter writer)
15 {
16 foreach (Control c in Controls)
17 {
18 c.RenderControl(writer);
19 }
20 }
2 {
3 if(Visible)
4 {
5 Render(writer);
6 }
7 }
8
9 protected virtual new void Render (System.Web.UI.HtmlTextWriter writer)
10 {
11 RenderChildren(writer);
12 }
13
14 protected virtual new void RenderChildren (System.Web.UI.HtmlTextWriter writer)
15 {
16 foreach (Control c in Controls)
17 {
18 c.RenderControl(writer);
19 }
20 }
从Control类派生控件时,可以重载Render方法来向响应流里写入标记文本。
使用HtmlTextWriter对象的标签和标签生成功能关联的HtmlTextWriterTag和HtmlTextWriterAttribute枚举类型能够简化代码、减少错误并使代码具有更好的可读性。
HtmlTextWriter:由System.IO.TextWriter派生,System.IO.TextWriter提供了向输出流中写入文本的功能。通过提供一种简化写入和格式化HTML标签和attribute的方法,HtmlTextWriter增加了基类的功能。
HtmlTextWriter相关枚举类型:HtmlTextWriterTag、HtmlTextWriterAttribute、HtmlTextWriterStyle
WebControl类的rendering方法
·protected virtual new void AddAttributesToRender ( System.Web.UI.HtmlTextWriter writer )
使Web控件指定名/值对,作为HTML元素标签的attribute提供。在重载AddAttributeToRender时,必须调用基类中相应的方法,否则控件将失去重要的功能。WebControl基类按照这种方式实现将会生成大量控件属性作为HTML attribute。
·public virtual new void RenderBeginTag ( System.Web.UI.HtmlTextWriter writer )
使Web控件在输出流中写一个开始标签,如果想对开始标签进行不同的处理,需要重载这个方法。如果控件只生成一个标签并想重载WebControl产生的默认<span>标签,应该重载TagKey或TagName属性。
·protected virtual new void RenderContents ( System.Web.UI.HtmlTextWriter writer )
使Web控件生成控件标签内的内容。默认情况下,本方法会生成子控件树。如果要在控件的标签中写入文本或其他内容,需要重载这个方法。如果要使用默认逻辑来产生子控件,需要调用基类的相应方法。
·public virtual new void RenderEndTag ( System.Web.UI.HtmlTextWriter writer )
使Web控件在输出流中写入一个结束标签。只有提供的结束标志匹配按照RenderBeginTag方法(如果在控件中重载此方法)创建的标签时,才需要重载此方法。
Web控件生成逻辑:
1 protected override void Render (System.Web.UI.HtmlTextWriter writer)
2 {
3 RenderBeginTag(writer);
4 RenderContents(writer);
5 RenderEndTag(writer);
6 }
7
8 public virtual new void RenderBeginTag (System.Web.UI.HtmlTextWriter writer)
9 {
10 AddAttributesToRender(writer);
11 HtmlTextWriterTag tagKey = TagKey;
12 if (tagKey != HtmlTextWriterTag.Unknown)
13 {
14 writer.RenderBeginTag(tagKey);
15 }
16 else
17 {
18 writer.RenderBeginTag(this.TagName);
19 }
20 }
21
22 protected virtual new void RenderContents (System.Web.UI.HtmlTextWriter writer)
23 {
24 base.Render(writer);
25 }
2 {
3 RenderBeginTag(writer);
4 RenderContents(writer);
5 RenderEndTag(writer);
6 }
7
8 public virtual new void RenderBeginTag (System.Web.UI.HtmlTextWriter writer)
9 {
10 AddAttributesToRender(writer);
11 HtmlTextWriterTag tagKey = TagKey;
12 if (tagKey != HtmlTextWriterTag.Unknown)
13 {
14 writer.RenderBeginTag(tagKey);
15 }
16 else
17 {
18 writer.RenderBeginTag(this.TagName);
19 }
20 }
21
22 protected virtual new void RenderContents (System.Web.UI.HtmlTextWriter writer)
23 {
24 base.Render(writer);
25 }
·在调用RenderBeginTag方法之前,必须提供标签的所有attribute和样式attribute,这是因为HtmlTextWriter对象在开始写标签的时候需要它们的attribute信息;
·需要分别单独调用AddStyleAttribute来传递每个样式attribute,HtmlTextWriter将所有的样式attribute合并到一个以分号分割的列表之中;
·每调用一次RenderBeginTag方法必须对应调用一次RenderEndTag方法,这同样适用于那些在HTML中没有对应的结束标记的标签,如<input>;
·name attribute为控件生成表单输入元素的唯一name,这样的元素才能参与到数据处理过程的回传中,标准ASP.NET表单控件将控件的UniqueID分配给name attribute,如果拥有多个表单元素,就必须基于控件UniqueID为每个元素创建不同的名字;
·id attribute用于客户端教本访问,每个元素中的id必须是唯一的,利用页面框架的ClientID属性来生成唯一的id attribute,默认情况下,WebControl生成ClientID属性作为HTML id。
低版本生成
HtmlTextWriter类有两个版本:HtmlTextWriter、Html32TextWriter
HtmlTextWriter:输出 HTML 4.0 代码
Html32TextWriter:派生自HtmlTextWriter,输出 HTML 3.2 代码
当页面收到一个Web请求时,它利用服务器的 HTTP_USER_AGENT 变量来检测浏览器的类型,并根据 web.config 文件的定义为得到的浏览器类型创建相应的 HtmlTextWriter。正确的 HtmlTextWriter 对象就是这样被自动传递给控件内的 rendering 方法。
前提:只有使用 HtmlTextWriterTag 枚举类型来生成标签,控件才能使用 HtmlTextWriter 对象提供的自动标签转换功能。
可以通过 Page 指令中的 ClientTarget attribute 指定目标浏览器,这个 attribute 将会重载自动浏览器检测,导致创建映射到该 attribute 值指定的浏览器的 HtmlTextWriter。
1 <%@ Page Language="C#" ClientTarget="downlevel" %>
posted on 2006-01-07 15:30 ............. 阅读(203) 评论(0) 收藏 举报
浙公网安备 33010602011771号