GridView 是 WebForms 核心資料展示控件。本文以「部門管理」為例,完整示範:欄位定義、資料繫結、DataKeyNames 主鍵綁定、RowDataBound 註冊客戶端亮列/刪除確認、RowDeleting 伺服端安全刪除與重新繫結。
<asp:GridView ID="gvDepartList" runat="server"
AutoGenerateColumns="False"
DataKeyNames="DepartId" <!-- 關鍵:主鍵欄位,不顯示於介面但供伺服端取用 -->
OnRowDeleting="gvDepartList_RowDeleting"
OnRowDataBound="gvDepartList_RowDataBound"
Width="600px">
<Columns>
<asp:TemplateField HeaderText="部門名稱">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("DepartName") %>' Style="text-align:center" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="機構" DataField="BranchId" />
<asp:BoundField HeaderText="負責人" DataField="PrincipalUser" />
<asp:BoundField HeaderText="聯系電話" DataField="ConnectTelNo" />
<asp:BoundField HeaderText="移動電話" DataField="ConnectMobileTelNo" />
<asp:BoundField HeaderText="傳真" DataField="Faxes" />
<asp:TemplateField HeaderText="修改">
<ItemTemplate>
<asp:ImageButton ID="imgEdit" runat="server"
ImageUrl="../images/edit.gif"
CommandName="Edit"
CommandArgument='<%# Eval("DepartId") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="刪除">
<ItemTemplate>
<asp:ImageButton ID="imgDelete" runat="server"
ImageUrl="../images/delete.gif"
CommandName="Delete" <!-- 觸發 RowDeleting -->
CommandArgument='<%# Eval("DepartId") %>'
OnClientClick="return confirm('確定刪除嗎?');" /> <!-- 客戶端確認 -->
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) BindData();
}
private void BindData() {
gvDepartList.DataSource = new DepartInfoManager().GetDepartInfos(-1);
gvDepartList.DataBind();
}
protected void gvDepartList_RowDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow) {
// 滑鼠進入/離開切換背景色
e.Row.Attributes["onmouseover"] = "currentcolor=this.style.backgroundColor;this.style.backgroundColor='#6699ff';";
e.Row.Attributes["onmouseout"] = "this.style.backgroundColor=currentcolor;";
// 也可在這裡針對特定按鈕加確認,但建議直接在標記用 OnClientClick
}
}
protected void gvDepartList_RowDeleting(object sender, GridViewDeleteEventArgs e) {
// 方式一:透過 DataKeys 取得主鍵 (推薦,不依賴控件結構)
string departId = gvDepartList.DataKeys[e.RowIndex].Value.ToString();
// 方式二:透過 CommandArgument (備選,需 FindControl)
// ImageButton btn = (ImageButton)gvDepartList.Rows[e.RowIndex].FindControl("imgDelete");
// string departId = btn.CommandArgument;
DepartInfoManager mgr = new DepartInfoManager();
if (mgr.DeleteDepart(departId)) {
// 刪除成功:重新繫結 + 友善提示
BindData();
ShowMessage("刪除成功!", MessageType.Success);
} else {
ShowMessage("刪除失敗,請稍後再試。", MessageType.Error);
}
}
| 實踐 | 說明 |
|---|---|
DataKeyNames | 主鍵不顯示於畫面,RowDeleting 直接用 DataKeys[e.RowIndex].Value 取得,安全且乾淨 |
CommandName="Delete" | 內建命令名,自動觸發 RowDeleting,無需自訂命令名 |
OnClientClick="return confirm(...)" | 客戶端攔截,取消時不回傳,減輕伺服器壓力 |
刪除後 BindData() | 重新查詢資料庫,確保畫面與資料一致 |
訊息提示用 Label 替代 alert() | 避免封鎖式對話框,體驗更佳;可用 UpdatePanel 局部更新 |
| 權限控管 | RowDataBound 中依角色隱藏/顯示刪除按鈕:e.Row.FindControl("imgDelete").Visible = HasDeletePermission(); |
DataKeyNames → 只能靠 FindControl 取 CommandArgument,易因控件 ID 變更而斷。AllowPaging="True" + PageSize,並處理 PageIndexChanging。using → 連線洩漏,資料庫連線池耗盡。新專案建議採用 ASP.NET Core + Razor Pages / MVC + 前端表格庫 (DataTables, AG Grid, TanStack Table),透過 Web API 取得 JSON 資料,前端負責渲染、排序、分頁、刪除確認,後端只提供 RESTful 端點,關注點分離更徹底。