浅述自定义控件(一)
1. 自定义控件概述
自定义控件常常继承于System.Web.UI.Control,System.Web.UI.WebControls.WebControl,System.Web.UI.WebControls.CompositeControl.
而CompositeControl类从WebControl继承,WebControl继承自Control类。
System.Web.UI.Control是所有ASP.NET控件的基类,继承自该基类的控件称之为完全自定义控件。
所有的Web控件都是从System.Web.UI.WebControls.WebControl继承而来,WebControl含有开始和结束标签,所以能获得更多的格式化选项,下面是两段代码:
首先是继承自Control:
public class FullyRenderControl : Control { public FullyRenderControl() { // //TODO: 在此处添加构造函数逻辑 // } protected override void Render(HtmlTextWriter writer) { writer.Write(Text); //base.Render(writer); } public string Text { get; set; } }而下面是继承自WebControl的方式:
public class FullyRenderControl : WebControl { public FullyRenderControl() { // //TODO: 在此处添加构造函数逻辑 // } protected override void RenderContents(System.Web.UI.HtmlTextWriter writer) { writer.Write(Text); } public string Text { get; set; } }将两者的自定义控件引用之后,运行的结果,引用的方式完全相同,可是当我们查看源文件时却会发现这样的差异:
首先是继承自Control的控件,生成了这样的HTML:
而继承自WebControl的控件则是这样的HTML:
正因为从WebControl生成的控件总是包含有开始和结束标签,所以他能获得更多的格式化选项,如Color,BackColor等。
举一个最简单的例子:Literal继承于Control,而Label就是继承于WebControl。从他们所拥有的属性我们则可以看出很大的问题了。
2. 常用类概述
HTMLTextWriter。在继承自WebControl的控件常用到这个类。
其实我个人认为他很类似与Servlet的out.,不过是封装了更多方法罢了。我不知道是不是该这么表述,我对JSP,Servlet的理解只限于能做出登录界面。
他可以写出各种各样的东西,例如Write,WriteBreak。当添加属性时,还可以用到这些枚举属性,例如:
当然为了吻合Web标准,也可以写入CSS属性:
在前文中,我们看到继承于WebControl的自定义控件产生的HTML代码中会自动加入<span>,当然,我们也可以自己指定加入的标签。
public class FullyRenderControl : WebControl { public FullyRenderControl() { // //TODO: 在此处添加构造函数逻辑 // } protected override void RenderContents(System.Web.UI.HtmlTextWriter writer) { writer.Write(Text); writer.WriteLine(); writer.Write(Text); } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Div; } } public string Text { get; set; } }3. 构建组合控件
组合控件是指继承与CompositeControl。组合控件可以用原有的ASP.NET服务器端控件。例如用一个TextBox加上一个RequiredFieldValidator控件组合而成一个不可空的TextBox。
但是我很少会使用这个,长长的指定属性往往让我望而生却…………………
在方法中,最常用的事件就是CreateChildControls和RenderContents。具体的可以参看MSDN。
4. 控件状态
ASP.NET Framework 2.0引入了控件状态的概念。
在之前有过视图状态这个概念,通常视图状态是用来存储控件的信息,来维护控件的状态。但是,通常情况下,为了优化性能,经常将视图禁用。但是,和视图状态不同的是,控件状态不能禁用。控件状态常常用于存储最重要的信息。
这样,即使当我们禁用了视图状态时,仍然会用控件状态来维护一些控件的重要信息。当我们自定义用户控件时,我们可以指定某控件的控件状态用来存储什么,例如下面的代码:
public class FullyRenderControl : WebControl { public FullyRenderControl() { // //TODO: 在此处添加构造函数逻辑 // } public string ControlState { get; set; } protected override void OnInit(EventArgs e) { Page.RegisterRequiresControlState(this);//将控件注册为具有持久性状态控件状态的控件 base.OnInit(e); } //返回保存的控件状态 protected override object SaveControlState() { return ControlState; } protected override void LoadControlState(object savedState) { ControlState = savedState.ToString(); } protected override void RenderContents(HtmlTextWriter writer) { writer.Write("ControlStateText:" + ControlState); writer.WriteBreak(); } }这样就公开了控件状态,这个时候外界就可以指定控件状态了。代码如下:
protected void Page_Load(object sender, EventArgs e) { this.FullyRenderControl1.ControlState = "Hello world"; }