GridView 列選取是常見需求。ASP.NET WebForms 提供兩種全選實作路徑:伺服器端(CheckBox AutoPostBack)與 客戶端(JavaScript 操作 DOM)。本文完整呈現雙方程式碼、運作差異、優缺點比較,並示範如何取得被選取列的 DataKey 值。
HeaderTemplate 放置 asp:CheckBox AutoPostBack="true" OnCheckedChanged="CheckAll",ItemTemplate 放置 asp:CheckBox ID="ItemCheckBox"。
<asp:GridView ID="GridView1" runat="server" DataKeyNames="序號" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Text="全選" AutoPostBack="true" OnCheckedChanged="CheckAll" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="ItemCheckBox" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="學生姓名" HeaderText="學生姓名" />
<asp:BoundField DataField="語文" HeaderText="語文" />
<asp:BoundField DataField="數學" HeaderText="數學" />
<asp:BoundField DataField="英語" HeaderText="英語" />
<asp:BoundField DataField="計算機" HeaderText="計算機" />
</Columns>
</asp:GridView>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="得到選擇的行值" />
protected void CheckAll(object sender, EventArgs e)
{
CheckBox cbx = (CheckBox)sender;
foreach (GridViewRow gvr in GridView1.Rows)
{
CheckBox ch = (CheckBox)gvr.FindControl("ItemCheckBox");
ch.Checked = cbx.Checked;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Ret1.Text = "";
foreach (GridViewRow gvr in GridView1.Rows)
{
CheckBox ch = (CheckBox)gvr.FindControl("ItemCheckBox");
if (ch.Checked)
{
Ret1.Text += "<li>GridView1 您選擇的是(鍵值):" + GridView1.DataKeys[gvr.DataItemIndex].Value;
}
}
}
HeaderTemplate 使用原生 <input type="checkbox" onclick="CheckAll(this)">,JavaScript 直接操作 GridView 渲染出的 HTML Table。
<asp:GridView ID="GridView2" runat="server" DataKeyNames="序號" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<input id="Checkbox2" type="checkbox" onclick="CheckAll(this)" runat="server" /><label>全選</label>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="ItemCheckBox" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="學生姓名" HeaderText="學生姓名" />
...
</Columns>
</asp:GridView>
<script type="text/javascript">
function CheckAll(oCheckbox) {
var gv = document.getElementById("<%=GridView2.ClientID %>");
for (var i = 1; i < gv.rows.length; i++) { // i=1 跳過 HeaderRow
var chk = gv.rows[i].cells[0].getElementsByTagName("INPUT")[0];
if (chk) chk.checked = oCheckbox.checked;
}
}
</script>
| 比較項目 | 伺服器端 | 客戶端 |
|---|---|---|
| 觸發機制 | Postback 觸發 CheckAll 事件 | 瀏覽器 JS 直接修改 DOM |
| 網路往返 | 完整 Postback,ViewState 往返 | 零網路流量,極速回應 |
| 狀態持久化 | 自動保留在 ViewState,Postback 後仍勾選 | 僅存在瀏覽器 DOM,Postback 後遺失(需自行同步) |
| 取得選取值 | 直接在後端迴圈 GridViewRows | 需配合隱藏欄位或 AJAX 送回伺服器 |
| 適用場景 | 需立即在後端處理選取資料、資料量小 | 純前端互動、大量資料、不想重整頁面 |
| DataKey 存取 | 直接用 GridView.DataKeys[index] | 需自行在渲染時輸出 DataKey 至隱藏欄位或 data-* 屬性 |
若採用客戶端全選,仍需在後端取得選取列,可採用下列任一策略:
<asp:HiddenField> 存放選取的 DataKey 清單(JSON 格式)。$.ajax 或 PageMethods 將選取清單送至 WebMethod/Service,不需整頁 Postback。ClientIDMode="Static" 可簡化 JS 選取器,否則需用 <%=GridView2.ClientID%>。Sys.Application.add_load 或 jQuery .on() 委派事件。伺服器端全選實作簡單、狀態自動管理,適合中小資料量且需即時後端處理的情境;客戶端全選體驗流暢、無閃爍,適合大量資料或單純前端互動,但需自行解決狀態持久化與後端取值問題。實務上常採「客戶端全選 + 隱藏欄位同步」混合模式,兼顧體驗與功能。