原文地址:http://www.dotblogs.com.tw/jeff377/archive/2008/03/17/1725.aspx
在 ASP.NET 的運行機制中,Button 的 Click 事件,一定會是 Page Load 事件之後。以下寫個簡單測試範例,在 Page Load 事件及 Button Click 事件分別 Response.Write 事件名稱,當按下按鈕時去觀查輸出的結果會發覺 Page Load 事件比 Button Click 事件先執行。
- Partial Class _Default
- Inherits System.Web.UI.Page
- Protected Sub Page_Load( ByVal sender As Object , ByVal e As System.EventArgs) Handles Me .Load
- Me .Response.Write( "Page_Load" )
- Me .Response.Write("
- ")
- End Sub
- Protected Sub Button1_Click( ByVal sender As Object , ByVal e As System.EventArgs) Handles Button1.Click
- Me .Response.Write( "Button1_Click" )
- Me .Response.Write("
- ")
- End Sub
- End Class
執行結果
至於為什麼會有這樣的結果呢?因為由 PostBack 動作所引發的控制項事件,是在 Page Load 中處理,此時會去檢查 Request.Form 的回傳值,再決定要引發的控制項事件。若需要在 Page Load 之前就要知道是那個 Button Click 動作,那就要自行由 Request.Form 中去判斷那個按鈕產生的 PostBack 動作。
一般 PostBack 的都是經由網頁 HTML 原始碼的 __doPostBack 函式處理 (註:Submit Button 並不會呼叫 __doPostBack 函式),__doPostBack 函式有 eventTarget 及 eventArgument 二個引數。其中 eventTarget 是產生 PostBack 的控制項,它會將值保留在 __EVENTTARGET 這個 HiddenField 中;eventArgument 是事件引數,它會將值保留在 __EVENTARGUMENT 這個 HiddenField 中。
- <input type= "hidden" name= "__EVENTTARGET" id= "__EVENTTARGET" value= "" />
- <input type="hidden" name= "__EVENTARGUMENT" id= "__EVENTARGUMENT" value= "" />
- <script type="text/javascript" >
- <!--
- var theForm = document.forms['form1'];
- if (!theForm) {
- theForm = document.form1;
- }
- function __doPostBack(eventTarget, eventArgument) {
- if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
- theForm.__EVENTTARGET.value = eventTarget;
- theForm.__EVENTARGUMENT.value = eventArgument;
- theForm.submit();
- }
- }
- // -->
- </script>
有上以上的基本認知,接下來就要實作如何在 Page Load 之前得知 Button Click 動作。首先在頁面上放置一個 Button 控制項,並將 UseSubmitBehavior 屬性設為 False。
- <asp:Button ID= "Button1" runat= "server" Text= "Button" UseSubmitBehavior= "False" />
執行程式,查看 Button 產生的 HTML 碼,可以發現 Button 的 onclick 呼叫 __doPostBack('Button1','') 去執行 PostBack 動作,它只能使 eventTarget 引數,而 eventArgument 是傳入空字串。eventTarget 引數值是 Client 端 Button 的 id (等於 Button 控制項的 ClientID)。
- <input type= "button" name= "Button1" value= "Button" onclick= "javascript:__doPostBack('Button1','')" id= "Button1" />
如果在 Page Init 事件就需要知道那個 Button Click 動作,就可以利用 __EVENTTARGET 這個 HiddenField 來判斷,若 __EVENTTARGET 等於 Button 的 ClientID 就代表是由那個 Button Click 產生的 PostBack 動作。
- Partial Class _Default
- Inherits System.Web.UI.Page
- Protected Sub Page_Init( ByVal sender As Object , ByVal e As System.EventArgs) Handles Me .Init
- '判斷 __EVENTTARGET HiddenField 的值,來判斷是否為 Button Click 產生的 PostBack 動作
- If Me .Request.Form( "__EVENTTARGET" ) = Button1.ClientID Then
- Me .Response.Write( "Page_Init 的 Button Click" )
- Me .Response.Write("
- ")
- End If
- End Sub
- Protected Sub Page_Load( ByVal sender As Object , ByVal e As System.EventArgs) Handles Me .Load
- Me .Response.Write( "Page_Load" )
- Me .Response.Write("
- ")
- End Sub
- Protected Sub Button1_Click( ByVal sender As Object , ByVal e As System.EventArgs) Handles Button1.Click
- Me .Response.Write( "Button1_Click" )
- Me .Response.Write("
- ")
- End Sub
- End Class
執行程式,當按下按鈕的執行結果如下。