第二篇:呈现内容_第三节:CompositeControl呈现

一、CompositeControl的呈现过程

CompositeControl派生自WebControls,重写了Render(HtmlTextWriter writer)方法。在调用基类WebControl的Render(HtmlTextWriter writer)方法前,先调用了EnsureChildControls()方法,以确保创建子控件。

protected internal override void Render(HtmlTextWriter writer)
 {

      if (base.DesignMode)

      {

          this.EnsureChildControls();

      }

      base.Render(writer);

 }

EnsureChildControls方法

该方法用于确定服务器控件是否创建了子控件或子控件是否在创建中。如果未创建子控件且子控件不在创建中,则创建子控件。该方法首先检查ChildControlsCreated属性的当前值。如果此值为false,则调用CreateChildControls方法。当需要确保已创建子控件时,将调用该方法。大多数情况下,自定义服务器控件的开发人员无须重写此方法。CompositeControl类继承自Control类的EnsureChildControls()方法源代码如下:

// System.Web.UI.Control
protected virtual void EnsureChildControls()

{

    if (!this.ChildControlsCreated && !this.flags[256])

    {

        this.flags.Set(256);

        try

        {

            this.ResolveAdapter();

            if (this.AdapterInternal != null)

            {

                this.AdapterInternal.CreateChildControls();

            }

            else

            {

                this.CreateChildControls();

            }

            this.ChildControlsCreated = true;

        }

        finally

        {

            this.flags.Clear(256);

        }

    }

}

private const int creatingControls = 256;    //Control类中定义的私有常量

ChildControlsCreated属性

该属性的数据类型为bool,其用于获取一个值,该值指示是否已创建服务器控件的子控件。如果已创建子控件则该属性为true;否则为false。该属性主要是为了避免CreateChildControls方法重复创建控件。

// System.Web.UI.Control
protected bool ChildControlsCreated

{

    get

    {

        return this.flags[8];

    }

    set

    {

        if (!value && this.flags[8])

        {

            this.Controls.Clear();

        }

        if (value)

        {

            this.flags.Set(8);

            return;

        }

        this.flags.Clear(8);

    }

}

CreateChildControls方法

重写从Control继承的受保护的CreateChildControls方法,以创建子控件的实例,并将它们添加到Controls集合,此方法可能会在页面和控件的生命周期内反复调用。为避免控件重复,ChildControlsCreated属性通常被设置为true。如果此属性返回true,则不再调用CreateChildControls方法。

// System.Web.UI.Control
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]

protected internal virtual void CreateChildControls()

{

}

二、从CompositeControl类派生"非空"文本控件

实现代码:

[ToolboxData("<{0}:NonEmptyBox runat=server></{0}:NonEmptyBox>")]
public class NonEmptyBox : CompositeControl

{

    private Label _lbInput;

    private TextBox _txtInput;

    private RequiredFieldValidator _rfvInput; //非空验证

    protected override void CreateChildControls()

    {

        this.Controls.Clear();

        _lbInput = new Label();

        _lbInput.ID = "lbInput";

        _lbInput.Text = this.LabelText;

        _txtInput = new TextBox();

        _txtInput.ID = "txtInput";

        _rfvInput = new RequiredFieldValidator();

        _rfvInput.ID = "rfvInput";

        _rfvInput.ErrorMessage = string.Format("{0}不能为空!",_lbInput.Text);

        _rfvInput.Text = "*";

        _rfvInput.Display = ValidatorDisplay.Dynamic;

        _lbInput.AssociatedControlID = _lbInput.ID;

        _rfvInput.ControlToValidate = _txtInput.ID;

        this.Controls.Add(_lbInput);

        this.Controls.Add(_txtInput);

        this.Controls.Add(_rfvInput);

        this.ChildControlsCreated = true;

    }

    public string LabelText

    {

        get

        {

            string labelText = (string)this.ViewState["LabelText"];

            if (labelText != null)

            {

                return labelText;

            }

            return string.Empty;

        }

        set

        {

            this.ViewState["LabelText"] = value;

        }

    }

}

测试代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="NonEmptyBoxTest.aspx.cs" Inherits="CustomServerControlTest.NonEmptyBoxTest" %> 
 

<%@ Register assembly="CustomServerControl" namespace="CustomServerControl" tagprefix="csc" %> 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

 

<html xmlns="http://www.w3.org/1999/xhtml"> 

<head runat="server"> 

<title></title> 

</head> 

<body> 

<form id="form1" runat="server"> 

<div> 

<csc:NonEmptyBox ID="NonEmptyBox1" runat="server" LabelText="姓名:" /> 

<csc:NonEmptyBox ID="NonEmptyBox2" runat="server" LabelText="住址:" /> 

<asp:Button ID="Button1" runat="server" Text=" 提 交 " /> 

<asp:ValidationSummary ID="ValidationSummary1" runat="server" /> 

</div> 

</form> 

</body> 

</html> 

测试截图:

NonEmptyBox 控件呈现的HTML:

<span id="NonEmptyBox1">
    <label for="NonEmptyBox1_lbInput" id="NonEmptyBox1_lbInput">姓名:</label>

    <input name="NonEmptyBox1$txtInput" type="text" id="NonEmptyBox1_txtInput" />

    <span id="NonEmptyBox1_rfvInput" style="color: Red; display: none;">*</span>

</span>

三、从CompositeControl类派生"邮箱地址"输入控件

实现代码:

[ToolboxData("<{0}:EmailInput runat=server></{0}:EmailInput>")]
public class EmailInput : CompositeControl

{

    private TextBox _txtEmail;

    private RequiredFieldValidator _rfvEmail; //非空验证

    private RegularExpressionValidator _revEmail; //格式验证

    protected override void CreateChildControls()

    {

        this.Controls.Clear();

        _txtEmail = new TextBox();

        _txtEmail.ID = "txtEmail";

        _rfvEmail = new RequiredFieldValidator();

        _rfvEmail.ID = "rfvEmail";

        _rfvEmail.ErrorMessage = "请输入邮箱地址!";

        _rfvEmail.Text = "*";

        _rfvEmail.Display = ValidatorDisplay.Dynamic;

        _rfvEmail.ControlToValidate = _txtEmail.ID;

        _revEmail = new RegularExpressionValidator();

        _revEmail.ID = "revEmail";

        _revEmail.ErrorMessage = "邮件格式错误!";

        _revEmail.Text = "*";

        _revEmail.Display = ValidatorDisplay.Dynamic;

        _revEmail.ValidationExpression = @"\w+([-+.‘]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";

        _revEmail.ControlToValidate = _txtEmail.ID;

        this.Controls.Add(_txtEmail);

        this.Controls.Add(_rfvEmail);

        this.Controls.Add(_revEmail);

        this.ChildControlsCreated = true; //在CreateChildControls()方法的最后把ChildControlsCreated设为true,这样就实现了既保证组合控件的子控件得以创建,又不会重复调用创建子控件的过程。

    }

    protected override HtmlTextWriterTag TagKey

    {

        get

        {

            return HtmlTextWriterTag.Table;

        }

    }

    protected override void RenderContents(HtmlTextWriter writer)

    {

        if (base.DesignMode)

        {

            this.EnsureChildControls(); //对于组合控件来说,最好在访问它的子控件之前添加对EnsureChildControls()的调用,避免在设计时遭遇空引用异常。

        }

        writer.RenderBeginTag(HtmlTextWriterTag.Tr);

        writer.AddAttribute(HtmlTextWriterAttribute.Align, "left");

        writer.AddAttribute(HtmlTextWriterAttribute.Width, "80px");

        writer.RenderBeginTag(HtmlTextWriterTag.Td);

        writer.Write("Email:");

        writer.RenderEndTag();

        writer.RenderBeginTag(HtmlTextWriterTag.Td);

        _txtEmail.RenderControl(writer);

        writer.RenderEndTag();

        writer.RenderBeginTag(HtmlTextWriterTag.Td);

        _rfvEmail.RenderControl(writer);

        _revEmail.RenderControl(writer);

        writer.RenderEndTag();

        writer.RenderEndTag();

    }

}

测试代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EmailInputTest.aspx.cs" Inherits="CustomServerControlTest.EmailInputTest" %> 
 

<%@ Register Assembly="CustomServerControl" Namespace="CustomServerControl" TagPrefix="csc" %> 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

 

<html xmlns="http://www.w3.org/1999/xhtml"> 

<head runat="server"> 

<title></title> 

</head> 

<body> 

<form id="form1" runat="server"> 

<div> 

<csc:EmailInput ID="EmailInput1" runat="server" /> 

<asp:Button ID="Button1" runat="server" Text=" 提 交 " /> 

<asp:ValidationSummary ID="ValidationSummary1" runat="server" /> 

</div> 

</form> 

</body> 

</html> 

测试截图:

EmailInput 控件呈现的HTML:

<table id="EmailInput1">
    <tr>

        <td align="left" width="80px">

            Email:

        </td>

        <td>

            <input name="EmailInput1$txtEmail" type="text" id="EmailInput1_txtEmail" />

        </td>

        <td>

            <span id="EmailInput1_rfvEmail" style="color: Red; display: none;">*</span>

            <span id="EmailInput1_revEmail" style="color: Red; display: none;">*</span>

        </td>

    </tr>

</table>

时间: 2024-08-09 17:14:02

第二篇:呈现内容_第三节:CompositeControl呈现的相关文章

第二篇:呈现内容_第二节:WebControl呈现

一.WebControl的呈现过程 WebControl派生自Control类,所以WebControl的呈现功能基于Control的呈现逻辑之上,但有了比较大的扩展. 首先,WebControl重写了Render(HtmlTextWriter writer)方法,将呈现的逻辑一分为三:RenderBeginTag().RenderContents().RenderEndTag().WebControl的这种设计基于一种假设:每个WebControl最终生成一个HTML控件(当然这个HTML控件

第二篇:呈现内容_第一节:Control&ldquo;画皮&rdquo;之旅

一.Control的呈现过程 在上个章节""生死有序"的控件生命周期"中,我们提到Render是控件开发的主角,但在控件树的"合成模式(Composite)"部分这位主角却缺席了(戏份太多的缘由).哦,好吧.主角现在登场. 1)控件树呈现的"合成模式(Composite)" 控件树的呈现过程是一个华丽的大圈,它从RenderControl(HtmlTextWriter writer)开始.从RenderChildrenInte

第二篇:呈现内容_第四节:个性化自定义控件

一.特性(Attribute): ①DefaultProperty:(例:[DefaultProperty("Text")]) DefaultProperty是用于设置控件的默认属性.例子中[DefaultProperty("Text")],就是当你选择这个控件的时候,在属性窗口中自动被选中的是Text属性. ②ToolboxData:(例:[ToolboxData("<{0}:NonEmptyBox runat=server></{0}

第二篇 Fiddler配置_浏览器&amp;手机

么是Fiddler? 网络项目的开发和测试中,Fiddler是强大的抓包工具,它的原理是以web代理服务器的形式进行工作的 ,可以说是非常常用的手头工具了,本文就Fiddler使用和配置进行说明. 代理就是在客户端和服务器之间设置一道关卡,客户端先将请求数据发送出去后,代理服务器会将数据包进行拦截,代理服务器再冒充客户端发送数据到服务器:同理,服务器将响应数据返回,代理服务器也会将数据拦截,再返回给客户端 了解HTTP协议 要分析Fiddler抓取的数据包,先要熟悉HTTP协议.HTTP即超文本

Python之路【第二篇】:Python基础(一)

Python之路[第二篇]:Python基础(一) 入门知识拾遗 一.作用域 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. 1 2 3 if 1==1:     name = 'wupeiqi' print  name 下面的结论对吗? 外层变量,可以被内层变量使用 内层变量,无法被外层变量使用 二.三元运算 1 result = 值1 if 条件 else 值2 如果条件为真:result = 值1如果条件为假:result = 值2 三.进制 二进制,01 八进

[C#] 软硬结合第二篇——酷我音乐盒的逆天玩法

1.灵感来源: LZ是纯宅男,一天从早上8:00起一直要呆在电脑旁到晚上12:00左右吧~平时也没人来闲聊几句,刷空间暑假也没啥动态,听音乐吧...~有些确实不好听,于是就不得不打断手头的工作去点击下一曲或是找个好听的歌来听...但是,[移动手锁定鼠标-->移动鼠标关闭当前页面选择音乐软件页面-->选择合适的音乐-->恢复原来的界面] 这一过程也会烦人不少,如果说软件的设计要在用户体验上做足功夫,感觉这一点是软件设计人员很难管住的方面,毕竟操作系统也就这样安排的嘛(当然,有些机智的开发人

jquery jtemplates.js模板渲染引擎的详细用法第二篇

jquery jtemplates.js模板渲染引擎的详细用法第二篇 关于jtemplates.js的用法在第一篇中已经讲过了,这里就直接上代码,不同之处是绑定模板的方式,这里讲模板的数据专门写一个template.html的文件来展示 <span style="font-family:Microsoft YaHei;font-size:14px;"><!doctype html> <html lang="zh-CN"> <

Web前端学习第二篇

今天看到了一篇写的不错的文章,是有关对JQuery.js等一些源代码初识的内容,感觉写的还是不错,所以拿过来分享一下. 文章的地址:http://my249645546.iteye.com/blog/1716629 1.对(function(){})(); 几乎所有的开源js代码开篇都是这样(function(……){……})(……); 下面是Jquery的部分源码: (function( window, undefined ) { var jQuery = function( selector

第二篇 SQL Server代理作业步骤和子系统

本篇文章是SQL Server代理系列的第二篇,详细内容请参考原文. SQL Server代理作业由一系列的一个或多个作业步骤组成.一个作业步骤分配给一个特定的作业子系统(确定作业步骤去完成的工作).每个作业步骤运行于一个单独的安全上下文,尽管每个作业有一个所有者来决定谁可以修改作业.本篇主要关注组成SQL Server代理的作业步骤和子系统.快速回顾作业理解SQL Server代理作业的最佳方式是把相关联的 需要完成给定任务 的组件放在一个容器中.作业最主要的组件有作业步骤.计划.警告和通知.