ASP.NET控件开发学习笔记--第5回 HtmlTextWriter的相关枚举
第5回 HtmlTextWriter的相关枚举
HtmlTextWriter是什么?我们来看这句代码:
protected override void Render(HtmlTextWriter writer)
喔!原来是Control类中的虚方法Render()里的参数。这一回偷点懒,理论部分翻译《Professional ASP.NET 2.0 Server Control and Component Development》一书里对它的相关阐述,自己想多累,翻译大师写的东西就爽得多了!
在调用Control类的Render方法时,给HtmlTextWriter类的Write方法传递字符串会出造成以下问题:
l 字符串操作容易导致错误而编译器不能捕捉这些错误。例如下面的错误只会在运行时被捕捉:
Writer.Write(“<spon/>”);
l 您失去了Visual Studio的智能提示的支持。
l 您不得不为不同的浏览器编写不同的HTML标记。
HtmlTextWriterTag,HtmlTextWriterAttribute和HtmlTextWriterStyle枚举解决了所有的问题。HtmlTextWriterTag枚举值拥有和HTML4.0标签一样的名称,例如HtmlTextWriterTag.Span对应HTML<span>标签。HtmlTextWriterAttribute枚举值和HTML4.0的属性名称相同,如HtmlTextWriterAttribute.ID跟HTML的id属性相对应。最后,HtmlTextWriterStyle枚举值和CSS样式属性同名,如HtmlTextWriterStyle.Width跟CSS样式属性相对应。
这三个枚举提供了以下好处:
l 因为这三个枚举是C#中的类型,您可以从编译器的类型检查中得到好处,以避免相关字符串操作的问题。(译者注:也就是说当你的Write方法输出了错误的HTML代码编译器不会报错)
l Visual Studio为这些枚举提供了智能提示的支持。
l ASP.NET框架为这些枚举提供了两个版本。第一个版本编译按照标准的HTML4.0进行编译,另一个版本按照标准的HTML3.2进行编译。ASP.NET框架允许使用您的自定义控件的客户端配置它们的环境以使ASP.NET框架使用跟这些环境相对应的版本。您的自定义控件不需要为不同的浏览器创建不同的HTML标记文本。只要使用这些枚举,ASP.NET框架将会自动地使用正确的版本。如果使用字符串,将不会得到这些好处。
好,翻译完这段理论知识,大家对HtmlTextWriter里的枚举有了些感性的认识,先着手把我们的例子运用以上知识修改,然后再继续翻译。首先把上一回中的bin目录删除,这样做是为了避免bin文件夹中的DLL和App_Code文件夹中的cs控件冲突。如果没有App_Code文件夹,请建一个,然后把上一回中的linksList.cs文件拷贝到里面,打开并修改代码如下:
例5-1代码1:linksList.cs代码
using System.Web.UI;
using System.Data;
using System.Data.OleDb;
using System.ComponentModel;
[assembly:TagPrefix("MyControl", "CG")]
namespace MyControl
{
[DefaultPropertyAttribute("TitleText")]
[ToolboxData("<{0}:LinksControl "+
"TitleText='我的链接' "+
"XmlFileName='linksList.xml' "+
"runat='server'></{0}:LinksControl>")]
public class LinksControl:Control
{
private string _titleText;
private string _xmlFileName;
[BrowsableAttribute(true)]
[DescriptionAttribute("设置标题栏的名称")]
[DefaultValueAttribute("我的链接")]
[CategoryAttribute("外观")]
public virtual string TitleText
{
get { return _titleText; }
set { _titleText=value; }
}
[BrowsableAttribute(true)]
[DescriptionAttribute("存放链接的xml文件名")]
[DefaultValueAttribute("")]
[CategoryAttribute("数据")]
public virtual string XmlFileName
{
get { return _xmlFileName; }
set { _xmlFileName=value; }
}
protected override void Render(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
if (_titleText!=null)
{
writer.AddAttribute(HtmlTextWriterAttribute.Id, "caption");
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.Write(_titleText);
writer.RenderEndTag();
}
if (_xmlFileName != null)
{
DataSet ds = new DataSet();
ds.ReadXml(Page.Server.MapPath(_xmlFileName));
foreach (DataRow row in ds.Tables["link"].Rows)
{
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.AddAttribute(HtmlTextWriterAttribute.Href, row["url"].ToString());
writer.AddAttribute(HtmlTextWriterAttribute.Target, "_blank");
writer.RenderBeginTag(HtmlTextWriterTag.A);
writer.Write(row["name"].ToString());
writer.RenderEndTag();
writer.RenderEndTag();
}
}
writer.RenderEndTag();
}
}
}
确保例4-1中的linkslist.aspx文件和之前使用的linkslist.css文件还在,在浏览器中运行linksList.cs,结果是否还是老样子?只是这一次我们使用了上面所讲的三个枚举。这段代码我花了挺长时间调试,后面才知道要先AddAttribute(加属性)再RenderBeginTag(声明属性所在的标签),有点晕!总之掌握它需要多多练习。好,做完这个例子,大概也知道上面讲的是什么回事了,继续翻译。
HTML标记文本由HTML元素组成,如table,tr,td,th,select,option,input等等。一般情况下,HTML元素由以下五部分组成:
l 起始标签(opening tag),如<table>,<tr>,<td>,<th>,<select>,<option>,<input>等等
l 属性(Attribute),如id,name,type,value等等。一个元素的属性放在起始标签中,如:
<table id=”mytable” name=”mytable”>
l 样式属性(style attributes),诸如width,height等等。一个元素的样式属性放在起始标签中,并做为style属性的一部分如:
<table style = ”width:100px; height:200px”>
l 内容(Content),一个元素的内容由文本,其它元素或两者同时组成。
l 结束标签(closing tag),如</table>,</tr>等等。
可以使用HtmlTextWriter类中的方法输出以上部分:
l RenderBeginTag:描绘或产生一个HTML元素的起始标签。
l AddAttribute:每个元素可以通过调用这个方法一次以产生或描绘HTML元素起始标签中的属性。
l AddStyleAttribute:每个style属性可以通过调用这个方法一次以产生或描绘HTML元素的部分style属性。
l Write:HTML元素可以包含文本或其他元素,或两者皆有。使用Write方法以产生任何的文字内容,如string,int,float等等。您需要使用RenderBeginTab,AddAttribute,AddStyleAttribute和RenderEndTag方法来产生非文本内容,如一个元素的子元素。
l RenderEndTab:描绘或产生一个HTML元素的结束标签。
好,翻译完了,准备看《长江七号》,有什么问题下回再讲。