我这里来讲下asp.net中得 __doPostBack 函数,因为很多时候我们会对这个函数充满疑问。
你能在源代码中看到 __doPostBack函数的两个参数:
1) eventTarget
2) eventArgument
1)
eventTarget包含了触发postback的控件ID。
eventArgument 包含了这个控件的事件参数.
当我们把一个页面的数据发送到服务端, ASP .NET 指定 __EVENTTARGET 和__EVENTARGUMENT 值,用这种方式来决定是哪一个控件导致了页面被发送到服务端同时哪一个事件被处理了。
在任何asp.net的页面中包含了“__EVENTTARGET” 和 “__EVENTARGUMENT,”是自动声明的。
eventTarget 和eventArgument 的值被存储在隐藏的域中。
这两个隐藏的变量通过Form,Param变量集合能给被后台代码所接受识别。
如果我们指明了 __doPostBack函数,
我们就能知道通过 ASP .NET 的__doPostBack函数两个参数传递给 __EVENTTARGET 和__EVENTARGUMENT这两个隐藏域的值。
这之后,页面将会提交到服务端。
当页面被提交到服务端之后,这就好办了通过 __EVENTTARGET和 __EVENTARGUMENT 两个值,我们可以知道是哪个控件导致了页面的回发和哪一个事件将要被处理。
导致 postback的控件ID存储在 __EVENTTARGET 隐藏域中, 所以你可以知道是哪个控件导致了 postback.
<a id="LButton2" href="javascript:__doPostBack('Button1','')">LinkButton</a>
你可以看到用 href调用了函数 "__doPostBack('Button1','')" ,传递了 eventTarget 参数是 "Button1"
Ex.
我新建了一个
Default.aspx 页面
1) 向下面一样添加了两个隐藏域到form中。
<input type="hidden" name="__EVENTTARGET" value=""> <input type="hidden" name="__EVENTARGUMENT" value="">
2)添加下面的脚本到head中
<script type="text/javascript"> function __doPostBack(eventTarget, eventArgument) { document.Form1.__EVENTTARGET.value = eventTarget; document.Form1.__EVENTARGUMENT.value = eventArgument; document.Form1.submit(); } </script>
3) 添加两个控件
<a id="LButton2" href="javascript:__doPostBack('Button1','')">LinkButton</a> <asp:Button ID="Button1" runat="server" Text="Button" /> <asp:DropDownList ID="ddlBrand" runat="server" CssClass="select2" onchange="javascript:document.form1.__EVENTTARGET.value = 'ddlBrand';document.form1.__EVENTARGUMENT.value = ''; document.form1.submit();"> </asp:DropDownList>
4) 添加下面的代码到cs文件中:
protected void Button1_Click(object sender, EventArgs e) { ClientScript.RegisterStartupScript(typeof(string), "key", "<script>alert('Button1_Click')</script>"); } protected void LButton2_Click(object sender, EventArgs e) { ClientScript.RegisterStartupScript(typeof(string), "key1", "<script>alert('LButton2_Click')</script>"); }
5) 你可以用下面的方法捕获PostBack并且触发相应的事件:
在PageLoad方法:
string __EVENTTARGET = Request.Form["__EVENTTARGET"]; switch (__EVENTTARGET) { case "Button1": { Button1_Click(this, new EventArgs()); break; } case "LButton2": { LButton2_Click(this, new EventArgs()); break; } }
这样的话就会捕获被Posted过来的变量 "__EVENTTARGET" 接着有选择性的执行 Button1_Click还是LButton2_Click
当然你可以传递一些事件参数过来给后台使用:
javascript:__doPostBack('LButton2','传递一些事件参数到后台')
这样能被后台代码的 Request.Form["__EVENTARGUEMENT"]捕获。
这样呢 __doPostBack就讲述完毕。
例子讲完了我给大家说下为什么会有这个方法__doPostBack,我们都知道控件的回发到服务端能帮我们解决很多问题,但是在asp.net中能真正默认回发的控件只有Button和ImageButton(这两个控件回发很特殊,后面补充,
当然别的一些具备AutoPostBack属性的控件也可以回发,也会生成__doPostBack函数的处理代码)
所以别的控件为了实现回发就可以采用这种替代方案。----这就是这个方法的目的和存在意义。
刚才说到Button和ImageButton的特殊,为什么特殊呢?他们两的PostBack到服务端不是通过 __EVENTTARGET 和__EVENTARGUMENT参数传递,因为他们本身就实现了IPostBackEventHandler接口。
而是在Button的提交过程中,Button会将Button本身的ID作为Request.Form的一个Key,它的Value是Button的Text属性值,回传给服务器.所以可以在后台循环Form.Keys取到所提交的Button,以执行相应的函数.
ImgButton也差不多,不同就在于,它不是用ImageButton的ID作为Request.Form的Key,它是用ImageButton的ID加上.x和.y作为Key,
在Request.Form添加两上键值对,这两个键值应该是对应ImageButton的图片大小的,了解了这个规律后,我们仍然可以通过一定的方式得到是否是由ImageButton引发的PostBack.
那么怎么获取是哪个Button触发了PostBack呢?这样:
foreach (string str in Request.Form) { Control c = Page.FindControl(str); if (c is Button) { control = c; break; } }
至于ImageButton根据上面的规矩也是可以获取了。
效果如下: