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

简介:

一、CompositeControl的呈现过程

clipboard

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> 

测试截图:

clipboard[6]

clipboard[8]

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> 

测试截图:

clipboard[10]

clipboard[12]

clipboard[14]

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>
作者: 韩兆新
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
分类:  [06]ASP.NET相关

本文转自韩兆新博客博客园博客,原文链接:http://www.cnblogs.com/hanzhaoxin/p/4077464.html,如需转载请自行联系原作者
目录
相关文章
|
5月前
|
编解码 前端开发 JavaScript
带您一步步构建一个基本的动态新闻网站,包括页面布局、样式设计以及交互效果的实现
【6月更文挑战第14天】构建动态新闻网站实战项目,涉及页面布局、样式设计和交互实现。首页采用顶部导航栏、轮播图和新闻列表布局;新闻列表页按分类显示新闻,详情页展示完整内容并可添加相关推荐和评论。设计注重色彩搭配、字体选择和布局间距,实现轮播图效果、导航栏交互和响应式设计,提升用户体验。该项目有助于锻炼HTML和CSS技能,理解网页设计实际应用。
150 1
|
4月前
uniapp实战 —— 竖排多级分类展示
uniapp实战 —— 竖排多级分类展示
57 0
|
5月前
|
Linux iOS开发 MacOS
【随手记】maplotlib.use函数设置图像的呈现方式
【随手记】maplotlib.use函数设置图像的呈现方式
61 0
|
6月前
|
前端开发 定位技术
前端知识笔记(十七)———地图多点标注功能
前端知识笔记(十七)———地图多点标注功能
149 1
聊天框(番外篇)—如何实现@功能的整体删除
上一篇文章中,我们已经初步实现了聊天输入框,但其@功能是不完善的,例如无法整体删除、无法获取除用户名以外的数据(假设用户名不是唯一的)。有问题就要想办法解决,在网上百度了一圈后,倒是有一些收获。本文就着重解决@的整体删除以及获取额外数据。
1116 0
聊天框(番外篇)—如何实现@功能的整体删除
|
前端开发
|
数据采集 监控 数据可视化
做出酷炫的动态统计图表,不一定要写代码
首先这个名字很长的,就是上面 GDP 图表的作者 Jannchie见齐 基于 D3.js 开发的 将历史数据排名转化为动态柱状图图表 的项目,并在 github 上开源了。
|
前端开发 搜索推荐 索引
重学前端 5 # 如何运用语义类标签来呈现Wiki网页?
重学前端 5 # 如何运用语义类标签来呈现Wiki网页?
121 0
重学前端 5 # 如何运用语义类标签来呈现Wiki网页?
那些酷炫的网页你也可以做到——第五篇(表格标签)
那些酷炫的网页你也可以做到——第五篇(表格标签)
150 0
那些酷炫的网页你也可以做到——第五篇(表格标签)
下一篇
无影云桌面