构建自定义控件系列之一——概述
1、 概述
开始编写自定义控件之前,需要考虑两个问题:
·编写什么类型的控件?
·从什么类继承?
第一个问题:
自定义控件包括两种 基本类型:完全生成和组合控件
完全生成:需要从头开始开始指定所有控件呈现到浏览器的HTML内容。
组合控件:从现有的地控件构建新控件。
第二个问题:选择新控件的基类。可以从任何已有的ASP.NET控件派生出新控件。
构建基础控件时,一般从以下基类中派生:
System.Web.UI.Control
ASP.NET所有控件的基类
System.Web.UI.WebControls.WebControl
所有Web控件的基类
System.Web.UI.WebControls.CompositeControl
2.0新增类,该类可作用于任何组合控件的基类。CompositeControl自动为它的子控件创建命名容器,确保其所有字控件ID属性唯一,它还包含重写过的Controls属性,用于强制子控件显示在设计视图中。
其中:CompositeControl类从WebControl类继承,WebControl从Control继承。WebControl与Control的不同之处在于,从WebControl类派生的控件总是含有开始标签和结束标签,素有WebControl含有更多的格式化选项。如:Literal与Label。
1.1构建完全自定义控件
代码示例:FullyRenderedControl
相对于从Control基类派生控件,通过从WebControl基类继承来创建完全生成控件要好的多。从WebControl类继承时,可重写RenderContents()方法来代替Render()方法。
代码示例:FullyRenderedControl
WebControl默认生成封闭的<span>标签。
·理解HtmlTextWriter类:被设计成专门用来生成HTML,下面是部分方法:
AddAttribute()——给调用RenderBeginTag()生成的标签添加一个HTML属性。
AddStyleAttribute()——给调用RenderBeginTag()生成的标签添加一个CSS属性。
RenderBeginTag()——生成开始HTML标签
RenderEndTag()——生成结束标签
Writer()——呈现字符串到浏览器
WriterBreak()——生成<b r />到浏览器
在调用RenderBeginTag之前,可以多次调用AddAttribute和 AddStyleAttribute方法,所有这些属性都在调用RenderBeginTag方法之前添加到开始的HTML标签
注:AddAttribute和AddStyleAttribute方法是为紧随其后的RenderBeginTag方法输出的标签提供属性设置。
HtmlTextWriterTag——包含最常用的HTML标签列表
HtmlTextWriterAttribute——包含最常用的HTML属性列表
HtmlTextWriterStyle——包含最常用的CSS属性列表
代码示例:
1、HtmlTextWriterTest类,使用HtmlTextWriter类进行输出格式及属性的设置;
2、Glow类,重写WebControl的TagKey属性。
1.2构建组合控件
所有ASP.NET控件都有Controls属性表示它的所有子控件,如果为控件添加一个子控件,那么子控件在父控件生成时会自动生成。创建组合控件一般需要重写控件的CreateChildControls()方法,控件在构建它的子控件时调用该方法。
代码示例:自定义控件RequiredTextBox.cs:该自定义控件组合一个TextBox控件和RequiredFieldValidator控件。
1.3构建混合控件
纯粹的组合控件往往满足不了要求,一般组合控件重写CreateChildControls()方法后,也需要重写RenderControls()方法来构成混合控件。
代码示例:Login.cs
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace JerryShi.Controls
{
public class Login : CompositeControl
{
private TextBox txtUserName;
private TextBox txtPassword;
public string UserName
{
get
{
EnsureChildControls();
return txtUserName.Text;
}
set
{
EnsureChildControls();
txtUserName.Text = value;
}
}
public string Password
{
get
{
EnsureChildControls();
return txtPassword.Text;
}
set
{
EnsureChildControls();
txtPassword.Text = value;
}
}
//该属性改为Table后好像没有起作用,可以通过源代码查看
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Table;
}
}
protected override void CreateChildControls()
{
txtUserName = new TextBox();
txtUserName.ID = "txtUserName";
this.Controls.Add(txtUserName);
txtPassword = new TextBox();
txtPassword.ID = "txtPassword";
txtPassword.TextMode = TextBoxMode.Password;
this.Controls.Add(txtPassword);
}
public override void RenderControl(HtmlTextWriter writer)
{
//table
writer.RenderBeginTag(HtmlTextWriterTag.Table);
//The first row
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
//Render UserName Label
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.For, txtUserName.ClientID);
writer.RenderBeginTag(HtmlTextWriterTag.Label);
writer.Write("User Name:");
writer.RenderEndTag();
writer.RenderEndTag();
//Render UserName TextBox
writer.RenderBeginTag(HtmlTextWriterTag.Td);
txtUserName.RenderControl(writer);
writer.RenderEndTag();
//the first row
writer.RenderEndTag();
//The Second row
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
//Render Password Label
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.For, txtPassword.ClientID);
writer.RenderBeginTag(HtmlTextWriterTag.Label);
writer.Write("Password:");
writer.RenderEndTag();
writer.RenderEndTag();
//Render UserName TextBox
writer.RenderBeginTag(HtmlTextWriterTag.Td);
txtPassword.RenderControl(writer);
writer.RenderEndTag();
//the second row
writer.RenderEndTag();
//table
writer.RenderEndTag();
}
}
}