案例选自Club,TimePicker
1. 类层次
public class TimePicker : WebControl, INamingContainer
其中INamingContainer是一个标记接口,标识在 Page 对象的控件层次结构内创建新 ID 命名空间的容器控件。
2.重载的方法分析
2.1 创建子控件
CreateChildControls
base.CreateChildControls();
_innerList = new ListBox();
FillTimes(); // _innerList.Items.Add(i + ":00 AM");...
Controls.Add(_innerList);
2.2 绘制
2.2.1 OnPreRender
介绍:当从 ASP.NET 页请求自定义控件时,在页处理的 PreRender 阶段,会调用 OnPreRender 方法。
实现:
a. 调用基类方法,base.OnPreRender(e)
b. 把JavaScript脚本导出到页面上,Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "popup", sb.ToString(), true);
2.2.2 TagKey (Getter)
介绍:返回Web 服务器控件相对应的System.Web.UI.HtmlTextWriterTag 值,返回Div
protected override System.Web.UI.HtmlTextWriterTag TagKey
{ get { return HtmlTextWriterTag.Div; } }
2.2.3 AddAttributesToRender
介绍:将需要呈现的 HTML 属性和样式添加到指定的 System.Web.UI.HtmlTextWriter 中。
实现:
this.Width = new Unit(150);
this.Style.Add("display", "inline-table");
base.AddAttributesToRender(writer);
2.2.4 RenderContents(System.Web.UI.HtmlTextWriter writer)
介绍:将控件的内容呈现到指定的编写器中。
实现:
a. 给子控件_innerTbx增加属性,然后Render子控件。
_innerTbx.Attributes.Add("Align", "AbsMiddle");_innerTbx.Width = new Unit(100); _innerTbx.RenderControl(writer);
b.添加其它元素,添加元素的顺序是先添加属性,然后才写标签和内容。
writer.AddStyleAttribute("display", "block");
writer.RenderBeginTag(HtmlTextWriterTag.Span);
writer.Write(errorText);
writer.RenderEndTag();
2.3 属性getter实现
public System.DateTime SelectedTime的getter和setter第一行均调用了EnsureChildControls()。
EnsureChildControls,确定服务器控件是否包含子控件。如果不包含,则创建子控件。