王朝网络
分享
 
 
 

ASP.NET服务器控件之RenderContents

王朝asp·作者佚名  2006-11-24
宽屏版  字体: |||超大  

上一篇文章介绍了使用Control类的Render方法实现控件呈现的基本知识和示例应用。本文重点介绍另一种实现控件呈现的常用方法--使用WebControl类的RenderContents方法实现控件呈现。

基础知识

就服务器控件而言只存在两种情况:一种是具有外观可视化元素的控件,还有一种是不具有外观可视化元素的控件。如果需要开发的服务器控件包含可视化元素,那么多数情况下,建议开发人员创建继承自System.Web.UI.WebControls.WebControl基类的控件类。这种做法的主要原因是基于便捷性考虑。因为,WebControl类可提供服务器控件的部分与外观有关的公共属性、方法和事件等。通过该类定义的属性,可以控制服务器控件的外观和行为。例如,使用BackColor和ForeColor属性,可以分别控制服务器控件的背景色和前景颜色;在可以显示边框的控件上,可以通过设置BorderWidth、BorderStyle和BorderColor属性,控制边框宽度、边框样式和边框颜色;服务器控件的大小可以通过Height和Width属性来指定等等。如果控件基类是Control类,那么实现这些类似内容则非常繁琐。

在使用WebControl基类实现控件呈现的过程中,必然要使用该类所提供的属性和方法等成员对象。这是读者需要重点掌握的内容。另外,对于该基类的构造函数也是不容忽视的。下面首先从WebControl的构造函数开始入手进行讲解,随后将说明常见的成员对象。

WebControl类包括三个构造函数,它们都用于初始化WebControl类的新实例,然而它们之间还存在一些细小的差异。

(1)protected WebControl ()

该构造函数用于初始化表示Span HTML元素的WebControl类的新实例。通常情况下,开发人员并不直接调用此构造函数。相反,它通常由派生类的构造函数调用以将TagKey属性初始化为Span枚举值。在随后的示例中,将重写TagKey属性,从而调用此构造函数。

(2)public WebControl (HtmlTextWriterTag tag)

开发人员可使用此构造函数创建并初始化使用指定的System.Web.UI.HtmlTextWriterTag值的WebControl类的新实例。其中的参数tag表示HtmlTextWriterTag枚举值之一。可能读者对于HtmlTextWriterTag还不太熟悉。它是一个枚举类型,其枚举值多为HTML标记,例如,A、B、Bold、Button等等。

(3)protected WebControl (string tag)

使用此构造函数可创建并初始化使用指定的HTML标记的WebControl类的新实例。其中参数tag表示HTML标记。当使用该构造函数时一定要注意:不能直接调用此构造函数。相反,它通常由派生类的构造函数调用以初始化TagKey和TagName属性。

在了解了WebControl类的构造函数之后,读者还必须了解WebControl类的一些常用属性和方法。下面列举了这些常用成员对象,它们对于实现控件呈现有着重要意义。

(1)Attributes属性

该属性用于获取与控件的属性不对应的任意特性(只用于呈现)的集合,其属性类型为AttributeCollection。

(2)ControlStyle属性

该属性用于获取服务器控件的样式,它是Style类型。ControlStyle属性封装WebControl类的所有外观属性,如BorderColor和Font。

(3)TagKey属性

该属性用于获取与此服务器控件相对应的System.Web.UI.HtmlTextWriterTag值,其属性类型为HtmlTextWriterTag枚举。

(4)protected virtual void AddAttributeToRender(HtmlTextWriter writer);

该方法将需要呈现的HTML属性和样式添加到指定的System.Web.UI.HtmlTextWriter中。注意在重写过程中,一定要调用基类中相应的方法。

(5)public void ApplyStyle(Style s);

该方法将指定样式的所有非空白元素复制到控件,改写控件的所有现有的样式元素。

(6)public void MergeStyle(Style s);

该方法将指定样式的所有非空白元素复制到控件,但不改写该控件现有的任何样式元素。

(7)protected override void Render(HtmlTextWriter writer);方法

该方法重写了Control.Render。

(8)protected virtual void RenderContents(HtmlTextWriter writer);

该方法将控件的内容呈现到指定的编写器中。如果要在控件的标签中写入文本或其他内容,则需要重写该方法;如果要使用默认逻辑来呈现子控件,那么一定要调用基类中相应的方法。

可能读者已经注意到WebControl基类中包括的两个方法:Render和RenderContents。根据上文所介绍的内容可知,Control基类中包括Render方法。由于WebControl类继承自Control类,因此,WebControl类中包含Render方法是无可非议的。然而,WebControl类中却有一个RenderContents方法,并且该方法与Render方法在功能、参数等方面都非常相似。那么在呈现控件过程中到底应该使用哪一个呢?

实际上,在通常情况下,如果服务器控件自WebControl基类派生,那么其中的Render方法很少使用,而主要使用RenderContents方法实现控件呈现。为了说明其中的原因,我们必须了解WebControl基类中Render方法的实现逻辑。

在WebControl基类中的Render方法的实现示意性代码如下所示:

protected override void Render(HtmlTextWriter output)

{

RenderBeginTag(output);

RenderContents(output);

RenderEndTag(output);

}

在WebControl基类中的RenderBeginTag方法的实现示意性代码如下:

public virtual void RenderBeginTag(HtmlTextWriter output)

{

AddAttributesToRender(output);

HtmlTextWriterTag tagKey = TagKey;

if(tagKey != HtmlTextWriterTag.Unknown)

{

output.RenderBeginTag(tagKey);

} else {

output.RenderBeginTag(this.TagName);

}

}

在WebControl基类中的RenderContents方法的实现示意性代码如下:

protected override void RenderContents(HtmlTextWriter output){

//使用默认逻辑来呈现子控件,那么一定要调用基类中的方法。

base.Render(output);

}

分析以上代码可以得出以下结论:

一、为了在由WebControl派生的类中实现控件呈现,必须重写AddAttributesToRender、RenderBeginTag、RenderEndTag、RenderContents等方法中的一个或者多个,而不必重写Render方法。

二、重写AddAttributesToRender、RenderBeginTag、RenderEndTag、RenderContents等方法非常重要(请注意重写这些方法的条件及注意事项),否则服务器控件可能会出现丢失标签的情况,这将严重影响服务器控件的呈现。

三、当呈现服务器控件标签中的内容时,必须重写RenderContents方法。

上文介绍了WebControl类的一些基本知识。尤其是对于上文所列举的示意性代码需要重点理解。这对于实现控件呈现有着重要作用。

应用示例

相信读者在浏览各个网站时,经常会看到"联系我们"等类似文字。当单击这些文字时,操作系统将自动打开自身所带的邮件客户端软件,提示用户发送邮件。本例将实现一个自定义服务器控件RenderContentsControl,其用于通过呈现包含"mailto:邮件地址"的超链接。本例的示例效果图如图1所示:

图1

如图1所示,页面中呈现了超链接文字"我的邮箱地址"。当单击该链接,系统将发送邮件给"my@mysample.com"。

在实现以上控件之前,首先应分析如下:本控件包含外观元素,例如,文字大小、颜色、是否粗体等。为此,控件基类不应从Control类继承,而应从WebControl类继承。这样,开发人员将不必自行实现这些外观样式属性等内容。

下面列举了实现自定义服务器控件的RenderContentsControl.cs文件源代码。

using System;

using System.ComponentModel;

using System.Security;

using System.Security.Permissions;

using System.Web;using System.Web.UI;

using System.Web.UI.WebControls;

namespace UsingRenderContentsControl{

[

AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal),

AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal), DefaultProperty("Email"), ParseChildren(true, "Text"),

ToolboxData("<{0}:RenderContentsControl runat=server></{0}:RenderContentsControl>")

]

public class RenderContentsControl : WebControl {

// 实现Email属性

[Bindable(true)]

[Category("Appearance")]

[DefaultValue("")] [Localizable(true)]

public string Email

{

get {

String s = (String)ViewState["Email"];

return ((s == null) ? String.Empty : s);

}

set {

ViewState["Email"] = value;

}

}

// 实现Text属性

[

Bindable(true), Category("Appearance"), DefaultValue(""), Localizable(true),

PersistenceMode(PersistenceMode.InnerDefaultProperty)

]

public virtual string Text

{

get {

string s = (string)ViewState["Text"];

return (s == null) ? String.Empty : s;

}

set {

ViewState["Text"] = value;

}

}

// 重写TagKey属性

protected override HtmlTextWriterTag TagKey

{

get {

return HtmlTextWriterTag.A;

}

}

// 重写AddAttributesToRender方法

protected override void AddAttributesToRender(HtmlTextWriter writer)

{

base.AddAttributesToRender(writer);

writer.AddAttribute(HtmlTextWriterAttribute.Href, "mailto:" + Email);

}

// 重写RenderContents方法

protected override void RenderContents(HtmlTextWriter writer)

{

if (Text == String.Empty) {

Text = Email;

}

writer.WriteEncodedText(Text);

}

}

}

如上代码所示,RenderContentsControl类继承自WebControl基类,其原因在前文已经说明。另外,在RenderContentsControl类的实现过程中,还包括了元数据属性标记、3个属性(Email、Text和TagKey)和2两个方法(AddAttributesToRender和RenderContents)实现等内容。下面逐一对这些内容进行分析。

代码说明之3个属性:

在上文代码中主要包括了3个属性:Email、Text和TagKey。Email属性用于获取或者设置具体的电子邮件地址,Text属性用于获取或者设置控件显示的文本内容。在这两个属性实现中,都使用了控件视图状态ViewState。服务器控件的视图状态为其所有属性值的累计。对于简单属性的实现,将经常使用ViewState。TagKey属性是重写属性,其继承自WebControl基类,这是读者需要理解的重点内容。重写TagKey属性主要是为了呈现HTML标记中的a元素,这样就不会呈现WebControl类所默认呈现的span元素。此处,也暗示了本控件使用的构造函数是继承自WebControl的protected WebControl (),读者可返回上文再看看有关这个构造函数的说明。需要读者牢记的是:如果要呈现的元素是HtmlTextWriterTag枚举的成员,则应重写TagKey属性。许多常见的HTML元素标记被映射为HtmlTextWriterTag枚举的值。例如,System.Web.UI.HtmlTextWriterTag.A与a元素对应,而System.Web.UI.HtmlTextWriterTag.Table与table元素对应。如果要呈现的元素不是由HtmlTextWriterTag枚举的成员表示,那么建议重写TagName属性,并返回要作为元素呈现的字符串。

代码说明之2个方法:

在RenderContentsControl服务器控件中重写了2个重要方法:一个是AddAttributesToRender、另一个是RenderContents。

(1)AddAttributesToRender

该方法用于为控件添加一个Href属性,并将该属性值设置为"mailto:Email",其中Email是上文所述的表示邮件地址的属性。当重写AddAttributesToRender方法时,应始终按照控件源代码演示的方式:首先,调用基类方法,然后进行相关设置。这样才能实现为服务器控件添加样式和其他属性的功能。实际上,根据前文所述的RenderBeginTag方法的实现示意性代码可知,AddAttributesToRender方法是由WebControl的RenderBeginTag方法调用。

(2)RenderContents

该方法是本示例的核心内容,其用于在控件的标记中写入由Text属性指定的超链接文本。如代码所示,服务器控件调用了HtmlTextWriter实例的WriteEncod

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有