asp.NET自定义服务器控件内部细节系列教程三
如大家要转载,请保留本人的版权:
/*
*Description:asp.NET自定义服务器控件内部细节系列教程
*Auther:崇崇-天真的好蓝
*MSN:chongchong2008@msn.com
*Dates:2007-05-20
*Copyright:ChongChong2008 YiChang HuBei China
*/
三 Control和WebControl
Control和WebControl相关Rendering方法中都使用了System.Web.UI.HtmlTextWriter对象,HtmlTextWriter是一个封装了响应流的类,派生自System.IO.TextWriter,提供了向输出流中写入文本的功能。
HtmlTextWriter对象常用的一些方法有:AddAttribute , AddStyleAttribute , RenderBeginTag , RenderEndTag 用来生成标签和标签属性。
HtmlTextWriter的各种方法的参数取值为以下三种枚举类型:HtmlTextWriterAttribute , HtmlTextWriterStyle , HtmlTextWriterTag 。
1.Control
Control类的保护属性:
Context : 是HttpContext类型,为当前的Web请求提供了访问System.Web.HttpContext对象的权限.
ViewStae : 是StateBag类型,状态信息字典,在回传中被串行化和往返传送
1.1 Control类的公共成员以及保护成员
public class Control : Icomponent , IParserAccessor
{
public Control();
//引用父控件相关
public virtual Page Page{get;set;}
public virtual Control Parent{get;}
public Control BindingContainer{get;}
public virtual Control NamingContainer{get;}
//标识
public virtual string ClientID{get;}
public virtual string ID{get;set;}
public virtual string UniqueID{get;}
//引用子控件相关
protected bool ChildControlsCreated{get;set}
public virtual ControlCollection Controls{get;}
protected virtual void CreateChildControls();
protected virtual ControlCollection CreateControlCollection();
protected virtual void EnsureChildControls();
public virtual bool HasControls();
public virtual Control FindControl(stirng id);
protected virtual void AddParsedSubObject(object obj);
//状态管理相关
public virtual bool EnabledViewState{get;set;}
protected bool HasChildViewState{get;}
protected bool IsTrackingViewState{get;}
protected virtual StateBag ViewState{get;}
protected void ClearChildViewState();
protected virtual void LoadViewState(object savedState);
protected virtual object SaveViewState();
protected virtual void TrackViewState();
//生成相关
public virtual bool Visible{get;set;}
protected virtual void Render(HtmlTextWriter writer);
protected virtual void RenderChildren(HtmlTextWriter writer);
public void RenderControl(HtmlTextWriter writer);
//数据绑定
public virtual void DataBind();
public ISite Site{get;set;}
public virtual void Dispose();
//帮助方法
protected virtual HttpContext Context{get;}
protected string MapPathSecure(string virtualPath);
public virtual string TemplateSourceDirectory{get;}
public string ResolveUrl(string relativeUrl);
//事件相关
public event EventHandler DataBinding;
public event EventHandler Disposed;
public event EventHandler Init;
public event EventHandler Load;
public event EventHandler PreRender;
public event EventHandler Unload;
protected virtual void OnDataBinding(EventArgs e) ;
protected virtual void OnInit(EventArgs e) ;
protected virtual void OnLoad(EventArgs e) ;
protected virtual void OnPreRender(EventArgs e) ;
protected virtual void OnUnload(EventArgs e) ;
protected EventHandlerList Events{get;} ;
protected virtual bool OnBubbleEvent(object source , EventArgs args) ;
protected void RaiseBubbleEvent(object source , EventArgs args) ;
}
1.2 Control的相关Rendering方法
1 public void RenderControl(HtmlTextWriter writer)
2 {
3 if(Viusible)
4 {
5 Render(writer);
6 }
7 }
生成一个控件,当页面生成控件树时,在每个子控件上都要调用RenderControl。当控件的visible属性为真时,RenderControl通过调用Render方法来实现。
protected virtual void Render(HtmlTextWriter writer)
{
RenderChildren( writer);
}
通过编写标记生成自身,当控件直接从Control派生时,应该重载这个方法来生成需要的内容。
protected virtual void RenderChildren(HtmlTextWriter writer)
{
foreach(Control c in Controls)
{
c.RenderControl(writer);
}
}
生成子控件,默认情况下子控件按照它们加入控件的Controls集合时的顺序生成。
从以上可以看出,页面将HtmlTextWriter对象传递给公共的RenderControl方法,RenderControl检查控件的Viusible属性是否为真,如果为真,RenderControl调用保护的Render方法,Render方法默认实现会调用RenderChildren方法,RenderChildren方法默认调用每个子控件的RenderControl方法,通过这种递归调用的方法就可以生成控件树。
2 WebControl
WebControl继承自Contrl,它重写了Render方法,实现了一段程序逻辑。
WebControl类的保护属性:
TagKey : 是HtmlTextWriterTag类型,重载这个属性来生成一个标准的HTML标签,以取代WebControl类生成默认的<span>标签
TagName : 是String类型,重载这个属性来生成一个非标准的HTML标签,而不是默认的<span>标签
2.1 WebControl的相关Rendering方法
protected override void Render(HtmlTextWriter writer)
{
RenderBeginTag(writer);
RenderContents(writer);
RenderEndTag(writer);
}
1 public virtual void RenderBeginTag(HtmlTextWriter writer)
2 {
3 AddAttributesToRender(Writer);
4 HtmlTextWriterTag tagKey = TagKey ;
5 if(tagKey != HtmlTextWriterTag.Unknown)
6 {
7 writer.RenderBeginTag(tagKey);
8 }
9 else
10 {
11 writer.RenderBeginTag(this.TabName);
12 }
13 }
1 protected virtual void RenderContents(HtmlTextWriter writer)
2 {
3 base.Render(writer);
4 }
1 public virtual void RenderEndTag(HtmlTextWriter writer)
2 {}
当需要生成Web控件标签中的内容时,需要重载RenderContents方法,在一些Web控件中,还需要重载Render方法。