页面的postback

     点击页面的控件会导致页面的postback,那么postback后页面是如何处理并且最终引发服务器端的事件的呢?下面我们就来简单的结合源代码叙述一下。

 

     

Code

 

 

 

1实现的 IPostBackEventHandler 接口来注册回传事件,并且需要在控件里面传递参数的。
eg:
table1.Attributes.Add("OnClick", this.Page.GetPostBackClientEvent(this, pMenuItem.ID));

在生成html页面 的注册形式变为:

OnClick="__doPostBack('ToolBar1','tbSave')"
OnClick="__doPostBack('ToolBar1','tbCancel')"

//实现   IPostBackEventHandler 接口的方法
void IPostBackEventHandler.RaisePostBackEvent(string itemID)
{
  this.OnMenuItemClick(new MenuItemClickEventArgs(this.SetMenuItemByitemID(itemID)));
}
其实这里也可以在OnPreRender中使用   this.Page.RegisterRequiresRaiseEvent(this);来强制调用 RaisePostBackEvent

2实现 IPostBackDataHandler 接口来注册回传事件,这里不需要传递参数。

因为通过调用方法 protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
postCollection[postDataKey]可以取到回传的数据进行处理,所以这里就需要控件存在一个 name = UniqueID 的input控件
private HtmlInputHidden SelectedTab;
this.SelectedTab = new HtmlInputHidden();
this.SelectedTab.ID = this.UniqueID;
如果没有这个 input控件,那么不会触发 LoadPostData方法了。
因为这个input控件 的 name和值会被加到 PostData键值对集合中去,而我们调用控件的 LoadPostData是根据PostData 里面的键数据找
到控件,然后调用的控件的LoadPostData 方法的。
其实这里也可以在OnPreRender中使用   this.Page.RegisterRequiresPostBack(this);来强制调用 LoadPostData

[EditorBrowsable(EditorBrowsableState.Advanced)]
public void RegisterRequiresPostBack(Control control)
{
    if (!(control is IPostBackDataHandler) && !(control._adapter is IPostBackDataHandler))
    {
        throw new HttpException(SR.GetString("Ctrl_not_data_handler"));
    }
    if (this._registeredControlsThatRequirePostBack == null)
    {
        this._registeredControlsThatRequirePostBack = new ArrayList();
    }
    this._registeredControlsThatRequirePostBack.Add(control.UniqueID);
}
看上面,这里是 Add 说明可以调用多个控件的 LoadPostData 方法的。这里
this._registeredControlsThatRequirePostBack 和 _registeredControlThatRequireRaiseEvent
是有区别的

 

在生成html页面 的注册形式变为:
onClick="Tab_OnSelectServerClick(this,'TabControl1:tabPage1');__doPostBack('TabControl1','')"

//实现   IPostBackDataHandler 接口的LoadPostData方法
protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
    base.ValidateEvent(postDataKey);
    string text = this.Text;
    string str2 = postCollection[postDataKey];
    if (!this.ReadOnly && !text.Equals(str2, StringComparison.Ordinal))
    {
        this.Text = str2;
        return true;
    }
    return false;
}
接着随着我们LoadPostData 的返回值来决定是否调用RaisePostDataChangedEvent 方法
protected virtual void RaisePostDataChangedEvent()
{

}

 

 

总结一下:
我们写控件的时候可以继承 IPostBackDataHandler IPostBackEventHandler
两个接口来来处理数据和回发页面
当我们的控件只继承IPostBackDataHandler 接口的话,我们在控件中必须满足条件:
控件里面存在一个 ID 为 UniqueID的input控件,或者在OnPreRender中使用   this.Page.RegisterRequiresPostBack(this);
只有这样 IPostBackDataHandler 中的 LoadPostData接口方法才会被调用。

而IPostBackDataHandler 接口中IPostBackDataHandler.RaisePostDataChangedEvent()方法是否被调用
是依靠LoadPostData 返回true 值来决定
如果LoadPostData 返回true

在这个控件里面触发事件的控件是HtmlInputButton,TextBox,CheckBox 或者 DropDownList 之类 那么它的 AutoPostBack 属性被设置成 true立刻回发,触发事件的控件是table,hr 等html元素,我们也可以依靠__dopostback()脚本 让页面立刻回发。
都不满足的话,而是等待有其他可以引起回发的控件(比如 Button, LinkButton 等)回发后,
只要一回发 方法RaisePostDataChangedEvent()必定执行

当我们控件只 继承 IPostBackEventHandler接口的时候 我们可以通过button,__dopostback()脚本(this.Page.GetPostBackClientEvent获得)回发页面并传递参数。

 

 

 

 

posted on 2008-08-14 15:55  kasafuma  阅读(552)  评论(0编辑  收藏  举报