青蛙煮酒论英雄 坐井观天话春秋

导航

学习自定义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事件! 这是为什么呢?因为http是无状态的,http服务器面对的是来自若干客户端的访问请求,它是无法为同一客户的连续访问保存状态的。举例来说,客户A在第一次访问时将变量a设置为1,第2次访问的时候a的值不是1而应该是初始值。怎么办呢?答案是使用ViewState。ViewState是asp.net提供的一种在web服务器和客户端往返数据的机制。存储在ViewState中的数据被保存到客户端,客户端回发时再将这些数据返回给服务器,这样就可以将新的数据和历史数据进行对比了:
      
 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));

posted on 2004-02-02 10:50  青蛙煮酒  阅读(2121)  评论(2编辑  收藏  举报