学习自定义web控件编程
要编写自定义web控件需继承System.Web.UI.Control,通过重写Render方法来呈现控件。无论多么复杂的web控件,其输出都是最基本的html元素,因此重写Render的关键是将web控件转化为html元素。Control类有一个可读写的ID属性,用来在服务器端唯一标识一个对象。Control类还有两个很重要的属性是ClientID和UniqueID,前者输出为html元素的id属性,后者输出为html元素的name属性。下面以一个自定义的TextBox作为说明,它实现了Text属性:
public class CustomTextBox : Control
{
private string _text;
public string Text
{
set{this._text = value;}
get{return this._text;}
}
protected override void Render(HtmlTextWriter writer)
{
writer.WriteBeginTag("input");
writer.WriteAttribute("name", this.UniqueID);
if(this.ID != null)
writer.WriteAttribute("id", this.ClientID);
writer.WriteAttribute("value", this.Text);
writer.Write(HtmlTextWriter.TagRightChar);
}
}
Render方法被asp.net调用,HtmlTextWriter对象由系统传入,以面向对象的方式输出html代码。
现在有两个问题需要解决:一是如何在回发后更新Text属性;二是如何实现TextBox控件的TextChanged事件。这需要通过实现IPostBackDataHandler的LoadPostData()方法和RaisePostDataChangedEvent()方法来实现。这两个方法都被asp.net来调用,前者用来读取用户在客户端用户对html元素输入的数据,如果LoasPostData()返回true的话,系统将调用RaisePostDataChangedEvent()。下面是添加的代码:
public bool LoadPostData(string postDataKey,
NameValueCollection postCollection)
{
string presentValue = this.Text;
this.Text = postCollection[postDataKey];
return (presentValue != this.Text);
}
public event EventHandler TextChanged;
public void RaisePostDataChangedEvent()
{
if(this.TextChanged != null)
this.TextChanged(this, new EventArgs());
}
以上的代码真的能够引发TextChanged事件么?能,一定能,即使用户未对html元素的值做任何改变都能在回发后引发TextChanged事件!
public string Text
{
set{this.ViewState["MyText"] = value;}
get{return (string)this.ViewState["MyText"];}
} protected bool _autoPostBack = false;
public bool AutoPostBack
{
set{this._autoPostBack = value;}
get{return this._autoPostBack;}
}
最后一个任务是实现AutoPostBack属性了。Asp.net为此提供了一个方法Page.GetPostBackEventReference(),它返回一段表示客户端事件的字符串,实际是一些客户端代码,只要在Render方法里插入下面的代码就行了,一个TextBox基本完成了!
if(this.AutoPostBack)
writer.WriteAttribute("onchange","javascript:" +
Page.GetPostBackEventReference(this));