在 ASP.NET WebForms 中,動態建立 GridView 的編輯、更新、取消按鈕時,常遭遇回發導致資料遺失、需在 Page_Load 重複 Bind()、甚至要在 RowDataBound 判斷 EditIndex 避免覆寫使用者輸入等棘手問題。本文提供兩種解決思路,並著重介紹透過模擬 __EVENTTARGET、__EVENTARGUMENT 讓動態按鈕正確觸發 GridView 內建命令的實作細節。
Bind(),點擊「編輯」正常進入編輯模式。Page_Load 每次回發都 Bind() 一次,但會導致使用者剛輸入的值被覆蓋,需在 RowDataBound 加上 if (e.Row.RowIndex == this.gvTypeList.EditIndex) return; 才能緩解,流程繁瑣且易出錯。將按鈕放在 UpdatePanel 外,透過 PageMethods 呼叫後端 WebMethod(本質是 Web Service),只傳輸必要資料,回傳 XML/JSON 結果。優點:回發負荷極小;缺點:對程式設計能力要求較高,複雜操作或大量資料不適用。
觀察 Trace 發現:
__EVENTTARGET = GridView ID,__EVENTARGUMENT = Edit$行索引。因此,只要在動態建立按鈕時,於 OnClientClick 注入 JavaScript 將這兩個欄位設為正確值,即可讓 GridView 正確識別命令。
public string GetPostBackJs(string Command, int Index) {
return string.Format(
"$('#__EVENTTARGET').val('{0}');$('#__EVENTARGUMENT').val('{1}');",
this.UniqueID, Command + "$" + Index.ToString());
}
OnClientClick:editTc.Controls.Add(new ImageButton() {
CommandName = CommandEnum.Cancel.ToString(),
ImageUrl = this.CancelImgUrl,
AlternateText = "取消",
OnClientClick = GetPostBackJs(CommandEnum.Cancel.ToString(), this.EditIndex)
});
如此一來,「更新」、「取消」按鈕點擊後即能正確觸發 GridView 的 RowUpdating、RowCancelingEdit 事件,無需在 Page_Load 重複綁定,也避免了資料被覆蓋的問題。
方案二利用 ASP.NET 原生 PostBack 機制,不引入額外架構,相容性佳,適合大多數動態 GridView 場景。若專案已大量使用 AJAX,方案一則能提供更流暢的使用者體驗。