数据和事件回发机制
其实这块知识在ASP.NET页面揭秘之页面生命周期都有提到过,但是并没有明确提出这个概念,在asp.net中通过视图机制实现两次页面请求之间的关联,视图区域信息存储在页面上的一个隐藏字段,里面存储每次需要视图机制保存的一些信息,每次提交时,都会以“客户端<==>服务器端”形式来回一次,当处理完成后,最后会以处理后的新结果作为新的视图信息存储到页面的隐藏字段,并与页面一起返回到客户端。
数据回发机制就是完成处理视图信息的功能。数据回发具体过程为,服务器端控件实现了IPostBackDataHandler接口,则当客户端提交后,就会有机会利用IPostBackDataHandler接口的LoadPostData方法,在该方法内部处理子控件的新旧值逻辑,这时视图信息数据以一个集合对象形式作为LoadPostData参数,并可以决定是否触发控件值变化后的事件。
IPostBackDataHandler接口包含LoadPostData(string postDataKey,NameValueCollection postCollection)和RaisePostDataChangeEvent()两个方法。LoadPostData用来检测提交给服务器数据,根据控件状态数据和回发数据是否发生更改而判断是否调用RaisePostDataChangeEvent方法,如果为true,.NET Fromewrok会自动调用RaisePostDataChangeEvent方法,就是将新值和旧值比较,如果不一样就需要数据回发了。
事件回发
要控件捕获回发事件,则它必须实现IPostBackEventHandler接口。此接口可以使服务器控件上触发的事件响应来自客户端的回发。该接口包含一个RaisePostBackEvent(string eventArgument)方法。
这里引用事件揭秘里出现过的一个例子
//声明一个委托
[SerializableAttribute]
[ComVisibleAttribute(true)]
public delegate void EventHandler (Object sender,EventArgs e)
[DefaultEvent("Click")]
[toolboxData("<{0}:PostBackEventControl runat=server></{0}:PostBackEventControl>")]
public class PostBackEventControl:Control,IPostBackEventHandler
{
//事件名称 编译器其实这里实行3个构造
public event EventHanlder Click;
//定义一个负责引发事件的方法来通知已订阅事件的对象事件已经发生
protected virtual void OnClick(EventArgs e)
{
if(Click!=null)
{
//是通知订阅对象(其实这里就是调用了服务器一个方法)
Click(this.e);
}
}
//触发事件
public void RaisePostBackEvent(string eventArgument)
{
//因为这里没有额外的信息传递所以赋空值
OnClick(EventArgs.Empty);
}
Protected overrrid void Render(HtmlTextWriter output)
{
output.Write("<INPUT TYPE=submit name="+this.UniqueID+"Value='单击我'/>");
}
}
在来看看该控件,按钮类型为:submit,其本身就可以提交事件到服务器,但是该控件还是不能捕捉到该按钮事件。它必须具备两个条件1.继承IPostBackEventHandler接口并实现接口中的方法。2。name值设置为 UniqueID。
“[DefaultEvent("Click")]”的功能是定义Click事件为默认事件。定义了默认事件,在设计器中双击控件就会从.aspx页切到.cs页,并可以自动注册默认事件
将事件与处理事件的方法相关联
This.button1.Clcik+=new EventHandler(Button1_Click);
这里可以参考委托揭秘
将对于不引起回发的HTML元素启动回发可以有以下几种方法
1.使用GetPostBackEventReference和GetPostBackClientHyperlink
将上面代码中TYPE=submit修改为button那么此按钮就不在具有回发到服务器的功能。那么此时如果使用GetPostBackEventReference就可以回发到服务器了。
这里介绍其中一个重载方法
public String GetPostBackEventReference(Control control,String argument)
前一个参数为一个控件,后一个可以是附加信息
修正以后给出代码
Output.Write(“<INPUT name=”+this.UniqueID+”Value=’单击我’ onclick=”+Page.ClientScript.GetPostBackEventReference(this,””));
这里ClientScript暂不做介绍。
从上面最终输出地HTML代码可以看到多了这么一个_doPostBack方法. eventTarget就是GetPostBackEventReference的第一参数,这里指当前控件,eventArgument就是GetPostBackEventReference的第二参数,为空。注意到最后提交窗体 “theForm.submit();”就实现了我们想要的回发。
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
2.GetPostBackClientHyperlink
Output.Write(“<a herf=”+ Page.ClientScript. GetPostBackClientHyperlink (this,””)+”>点击我</a>”);
也上产生与上面相同的效应。
如果我们要把服务器某些控件(必须实现IPostBackDataHandler接口)处理回发,那么可以通过Page.RegisterRequiresPostBack实现。例
TextBox txt=new TextBox();
Protect void Page_PreRender(object sender,EventArgs e)
{
This.Page. RegisterRequiresPostBack(txt);
}