博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

asp.net组件(7)数据回发 IPostBackDataHandler

Posted on 2007-12-19 20:01  a-peng  阅读(1115)  评论(0编辑  收藏  举报
先来做个实验:
新建一网页.拉入一个TextBox控件.双击它.则系统默认为其添加TextChanged事件的处理函数

protected void TextBox1_TextChanged(object sender, EventArgs e)
{
Response.Write("<script language='javascript'>alert('" + TextBox1.Text + "');</script>");
}

接着又拉入一个Button控件
运行程序,在textbox中输入任意字符串,点击,button触使页面回发.
弹出:输入的内容
在textbox中输入与刚才相同的字符串,点击,button触使页面回发.
不弹出任何东西

textbox是怎么做到获取字符串的改变呢?
查看sdk
public class TextBox : WebControl, IPostBackDataHandler
就是IPostBackDataHandler提供了这个魔力.

接下来干什么呢?当然是我们自己也做一个喽.来试试这个强大的功能.

using System;
using System.Collections.Specialized;
using System.Web.UI;

namespace WebComponent
{
    [ToolboxData(
@"<{0}:PostDataBackComponent runat='server'></{0}:PostDataBackComponent>")]
    
public class PostDataBackComponent : Control, IPostBackDataHandler
    
{
        
public PostDataBackComponent()
        
{ }

        
public string Text
        
{
            
get
            
{
                
object text = ViewState["Text"];
                
if (text == null)
                    
return string.Empty;
                
else
                    
return (string)text;
            }

            
set
            
{
                ViewState[
"Text"= value;
            }

        }
        
        
        
public event EventHandler TextChanged;

        
protected void OnTextChanged(EventArgs e)
        
{
            
if (TextChanged != null)
                TextChanged(
this, e);
        }


        
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
        
{
            
string postedData = postCollection[postDataKey];//回发回来的字符串

            
if (!this.Text.Equals(postedData))
            
{
                
this.Text = postedData;
                
return true;
            }

            
else
            
{
                
return false;
            }

        }


        
public void RaisePostDataChangedEvent()
        
{
            OnTextChanged(EventArgs.Empty);
        }


        
protected override void Render(HtmlTextWriter writer)
        
{
            
//base.Render(writer);
            writer.Write("<input type='text' name='" + this.UniqueID + "' value='" + this.Text + "'/>");
        }

    }

}

我们来分析下这个控件.
首先是Text这个属性:我们要模拟textbox控件的效果,所以也提供了一个text属性,
但就有个问题,如果在页面回发中保留输入字符串的值呢?

使用:ViewState["Text"]来保留住状态.返回类型是object所以需要对其强制转换.
还有一点说明一下:IPostBackDataHandler没有回发的功能,所以我们需要在页面中加个Button来回发.

页面回发后,页框架在发送的内容中搜索与实现 IPostBackDataHandler 的服务器控件的 UniqueID 匹配的值
然后,页框架按顺序在每个实现该接口的控件上调用 LoadPostData
那么LoadPostData有什么作用呢?主要作用是可以获取回发回来的数据.
string postedData = postCollection[postDataKey];//回发回来的字符串
postDataKey标识控件的关键字
postCollection发送数据的集合

LoadPostData的返回值为bool型.
return true则,将调用.RaisePostDataChangedEvent产生回发数据发生变化的事件
return false,当然就不产生喽.
所以LoadPostData中提供了回发的数据,就是让你比较,数据是否改变了.

说到这里就完了.
你可以试试拉两个DropDownList控件
一个的AutoPostBack为true ddlAutoPostBack
另一个的AutoPostBack为false ddlNotAutoPostBack
这个属性就是控件是否自动回发.也就是是否实现IPostBackEventHandler这个接口
DropDownList中有个SelectedIndexChanged事件
用来判断选中项是否改变,说明它实现了IPostBackDataHandler这个接口

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Ch07 : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    
{
        ddlAutoPostBack.SelectedIndexChanged 
+= new EventHandler(ddlAutoPostBack_SelectedIndexChanged);
        ddlNotAutoPostBack.SelectedIndexChanged 
+= new EventHandler(ddlNotAutoPostBack_SelectedIndexChanged);
        
if (!Page.IsPostBack)
        
{
            
string[] ddlDataSource = new string[] "aa""bb""cc" };

            ddlAutoPostBack.DataSource 
= ddlDataSource;
            ddlAutoPostBack.DataBind();

            ddlNotAutoPostBack.DataSource 
= ddlDataSource;
            ddlNotAutoPostBack.DataBind();
        }

    }


    
protected void ddlAutoPostBack_SelectedIndexChanged(object sender, EventArgs e)
    
{
        Response.Write(
"<script language='javascript'>alert('" + ddlAutoPostBack.SelectedValue + "');</script>");
    }


    
protected void ddlNotAutoPostBack_SelectedIndexChanged(object sender, EventArgs e)
    
{
        Response.Write(
"<script language='javascript'>alert('" + ddlNotAutoPostBack.SelectedValue + "');</script>");

    }


}

ddlNotAutoPostBack_SelectedIndexChanged永远也不会被执行.
因为ddlNotAutoPostBack的AutoPostBack为false