自定义控件的构建(6)

前面讲到了视图和控件状态,ASP.NET中有个概念叫做回传,因为ASP.NET框架是围绕Web表单构建的,回传即信息从客户端浏览器传递到服务器的过程。

那么这其中又分为2种情况:

当控件引起回传的时候,表单回传到服务器,会引发服务器控件,比如Button被单击时,Click事件则会再包含该Button的表单中回传给服务器,这也称为回传事件。

第2种情况则是,Web表单中的数据也可以传给控件。比如当表单包含TextBox时,表单中的数据会在Web表单提交到服务器时传递给TextBox,这个数据又称为回传数据。

下面分别说明这2种情况的实现

处理回传数据

这里主要使用到IPostBackDataHandler接口

namespace HandlePostBack
{
    //处理回传数据
    public class HandlePostDataControl:WebControl,IPostBackDataHandler
    {
        public event EventHandler TextChanged;
        public string Text
        {
            get
            {
                if (ViewState["Text"] == null)
                    return String.Empty;
                else
                    return (string)ViewState["Text"];
            }
            set
            {
                ViewState["Text"] = value;
            }
        }
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
            writer.AddAttribute(HtmlTextWriterAttribute.Value, Text);
            writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
            base.AddAttributesToRender(writer);
        }
        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            if (postCollection[postDataKey] != Text)
            {
                Text = postCollection[postDataKey];
                return true;            
            }
            return false;
        }
        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Input;
            }
        }
        public void RaisePostDataChangedEvent()
        {
            if (TextChanged != null)            
            {
                TextChanged(this, EventArgs.Empty);
            }
        }
    }
}

IPostBackDataHandler接口包括两个方法:LoadPostData用来检索从浏览器传回的表单域,其中第一个参数表示关联到当前控件的域的名字,RaisePostDataChangedEvent用来引发指示一个表单域值发生改变的事件,这里注意一点:如果表单域的名字与控件名字不匹配,则要实现上面的功能时,需要在控件的PreRender事件中调用Page.RegiseterRequiresPostBack(),通知页面这个控件有兴趣回收这个回传数据

上面的代码主要是让TextBox在页面回传中保存输入框的状态,并且在内容被修改后引发TextChanged事件,如果表单域的值和控件Text属性值不匹配,那么将更新Text属性并且返回True值,当LoadPostData返回True值时,就会执行RaisePostDataChangedEvent,一般都用这个方法实现一个事件。

处理回传事件

一次只能由一个控件引发表单提交至服务器的行为,同回传数据一样,其需要实现IPostBackEventHandler接口,这个接口包含了RaisePostBackEvent事件,用于控件引发回传时在服务器调用

namespace {
public class HandlePostEventControl : WebControl, IPostBackEventHandler
    {
        private string _Text;
        public string Text
        {
            get { return _Text; }
            set { _Text = value; }
        }
        public event EventHandler Click;
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            string eRef = Page.ClientScript.GetPostBackClientHyperlink(this, String.Empty);
            writer.AddAttribute(HtmlTextWriterAttribute.Href, eRef);
            base.AddAttributesToRender(writer);
        }
        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.A;
            }
        }
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write(_Text);
        }
        public void RaisePostBackEvent(string eventArgument)
        {
           if(Click!=null)
           {
               Click(this, EventArgs.Empty);
           }
        }
    }
}

这段代码主要示例了如何实现IPostBackEventHandler接口,这个自定义控件类似于LinkButton,在浏览器中单击该控件生成的连接时,包含该控件的表单就会

回传给服务器并调用RaisePostBackEvent()

这里需要注意的是AddAttributesToRender()中第一行代码,GetPostBackClientHyperlink()用于返回浏览器中引起表单回传的JS,它返回类似下面的js代码

javascript:_doPostBack('HandlePostEventControl1','') ;_doPostBack()用于调用客户端表单的submit().

代码演示:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TextPostBackControl.aspx.cs" Inherits="TextPostBackControl" %>
<%@ Register TagPrefix="handleps" Namespace="HandlePostBack"  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
     <div>
         <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
         <asp:Label ID="Label2" runat="server" Text="Label" EnableViewState="false"></asp:Label>
        <handleps:HandlePostEventControl ID="HandlePostEventControl1" runat="server" Text="submit" OnClick="EventControl1_Click" />
    </div>  
    </form>
</body>
</html>
后台代码:
 protected void EventControl1_Click(object sender, EventArgs e)
      {
        this.Label2.Text = HandlePostEventControl1.Text;
    }
       当单击这个自定义的按钮时,Click事件会将TextBox中的值显示在Label中

 

 

本文参考了《ASP.NET 揭秘(卷2)》

posted @ 2010-08-03 08:21  Ringgo.Yao  阅读(...)  评论(...编辑  收藏