PRB: ASP.NET 引發 Change 事件即使不變更控制項值

文章翻譯 文章翻譯
文章編號: 314809 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

徵狀

ASP.NET 會在特定情況下引發 [變更 ASP.NET 網頁的事件控制即使不變更控制項。

發生的原因

某些控制項,例如 SelectedIndexChanged 事件 DropDownList 控制項中的或在 TextBox 控制項中的 TextChanged 事件依賴使用檢視狀態變更事件的註冊。當您建立這些控制項以動態方式連結事件之後,就會發生這個問題。

當 ASP.NET 呈現至瀏覽器頁面時,以動態方式建立的控制項中沒有相關聯的 Change 事件。因為沒有事件存在所以 ASP.NET 不會儲存檢視狀態。這就稱為檢視狀態最佳化。

頁面張貼回時和事件攔截時,ASP.NET 就會預期檢視狀態,但找到都不存在。即使不變更控制項,這項差異就會引發 Change 事件。

解決方案

請確定您連接向上動態建立控制項的 Change 事件,ASP.NET 會呈現在頁面之前。這樣可以確保控制項的檢視狀態存在。

狀況說明

這種行為是經過設計規劃的。

其他相關資訊

重製行為的步驟

建立 Web 表單

  1. 建立新的 Visual Basic ASP.NET 應用程式,名為 ChangeFired。
  2. 在設計工具的模式中開啟 WebForm1。將 資料清單 控制項、 按鈕 控制項和 DataSet 控制項拖曳至表單。
  3. 加入資料集] 對話方塊按一下 不具型別資料集,再按 [確定]。保留的所有控制項的預設名稱。
  4. 編輯為 DataSet1 Tables 集合。加入新的資料表名稱為 Table1。
  5. 編輯為 Table1 之資料行集合。新增名為欄 1 的新資料行。
  6. 按一下 DataList1,並接著將 資料來源 屬性變更為 DataSet1
  7. DataList1] 上按一下滑鼠右鍵,指向 [編輯樣板],然後再按一下 [項目樣板。將 DropDownList 控制項拖曳至 [標記] 區段。
  8. 按一下 DropDownList1,然後再將五個項目加入至項目集合。文字 和這些項目 屬性分別設定為 兩個四個,及 五個
  9. AutoPostBack 屬性設定為 true 中,針對 DropDownList1。
  10. 編輯為 DropDownList1 之資料繫結集合。將下列的自訂繫結運算式加入至 SelectedIndex 屬性:
    DataBinder.Eval(Container, "DataItem.Column1")
    					
  11. 切換至 HTML 檢視。追蹤 屬性設定為 true@ Page 指示詞中,如下所示:
    <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" 
    Inherits="ChangeFired.WebForm1" trace="true" %>
    					

加入程式碼後置檔案

  1. 的 WebForm1.aspx 上按一下滑鼠右鍵,然後按一下 [檢視程式碼
  2. 加入下列程式碼,以 Page_Load 事件:
    DataSet1.Tables(0).Rows.Add(New Object() {"1"})
    DataSet1.Tables(0).Rows.Add(New Object() {"2"})
    DataSet1.Tables(0).Rows.Add(New Object() {"3"})
    DataSet1.Tables(0).Rows.Add(New Object() {"4"})
    
    If Not IsPostBack Then
      DataBind()
    End If
    
    Dim objItem As DataListItem
    For Each objItem In DataList1.Items
      AddHandler CType(objItem.FindControl("DropDownList1"), _
      DropDownList).SelectedIndexChanged, AddressOf DropDownList1_SelectedIndexChanged
      If Not objItem.FindControl("DropDownList1") Is Nothing Then
        Trace.Write("Added SelectedIndexChanged Handler")
      End If
    Next
    					
  3. 建立新的 Sub 程序下方 Page_Load 事件處理 SelectedIndexChanged 事件,如下所示:
    Private Sub DropDownList1_SelectedIndexChanged(ByVal sender As System.Object, _
    ByVal e As System.EventArgs)
      DataBind()
      Trace.Write("SelectedIndexChanged, DataBind()")
    
      'Uncomment the following code to resolve this problem.
      'Dim objItem As DataListItem
      'For Each objItem In DataList1.Items
      '  AddHandler CType(objItem.FindControl("DropDownList1"), _
      '  DropDownList).SelectedIndexChanged, AddressOf DropDownList1_SelectedIndexChanged
      'Next
    End Sub
    					

執行範例

  1. 執行網頁。請注意動態建立的 DropDownList 控制項包含追蹤資訊的控制項樹狀目錄中的檢視狀態。

    這是因為呼叫 DataBind 方法動態地建立 DropDownList 的控制項,您連接事件處理常式之後在 Page_Load 事件中呼叫 DataBind。因為控制項具有事件處理常式,檢視狀態最佳化不會發生。
  2. 按一下 [在頁面] 按鈕。請注意張貼回,就會發生,而且只在 Page_Load 事件內程式碼會執行。對於 DropDownList 控制項的檢視狀態存在,因為事件處理常式與控制項相關聯。
  3. 變更其中一個 DropDownList 控制項值。請注意張貼回就會發生。在另外請注意 ASP.NET 會引發 Page_Load 事件,而且執行 DropDownList1_SelectedIndexChanged 事件。
  4. DropDownList1_SelectedIndexChanged] 事件中呼叫 DataBind 方法,一次以建立新的 DropDownList 控制項。

    因為 SelectedIndexChanged 事件未連結到這些新的 DropDownList 控制項,ASP.NET 會使用檢視狀態最佳化,並不會儲存在新的 DropDownList 控制項檢視狀態。
  5. 檢閱追蹤資訊的控制項樹狀目錄。請注意 DropDownList 控制項沒有檢視狀態中。
  6. 按一下 [在頁面] 按鈕。請注意就會發生張貼回,並請注意,ASP.NET 執行 Page_Load 事件。因為您攔截 (Hook SelectedIndexChanged 事件至 DropDownList 控制項 ASP.NET 所預期要與控制項關聯的檢視狀態。

    不過,因為檢視狀態並不存在,ASP.NET 引發 SelectedIndexChanged] 事件即使您沒有選取項目。

解決方案

取消程式如果要解決這個問題,碼的註解 DropDownList1_SelectedIndexChanged 事件中,讓事件處理常式攔截與新建立的控制項。

屬性

文章編號: 314809 - 上次校閱: 2004年5月3日 - 版次: 2.7
這篇文章中的資訊適用於:
  • Microsoft ASP.NET 1.1
  • Microsoft ASP.NET 1.0
關鍵字:?
kbmt kbdatabinding kbevent kbprb kbservercontrols kbstate kbwebforms KB314809 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:314809
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com