• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

Stand By .NET

.NET & SQL Server
  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

第八章 生成

    不要从控件里调用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方法。通过这种递归调用的方法就可以生成控件树。
 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 }

    从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 }

    ·在调用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)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3