預設 GridView 單列編輯 (EditIndex)。批次更新需所有列同時進入編輯模式。解法:將 BoundField 轉為 TemplateField,在 ItemTemplate 直接放入編輯控制項 (TextBox, DropDownList),配合「更新所有」按鈕與事務。
<asp:GridView ID="gvProducts" runat="server" AutoGenerateColumns="False"
DataSourceID="odsProducts" DataKeyNames="ProductID">
<Columns>
<asp:TemplateField HeaderText="產品名稱">
<ItemTemplate>
<asp:TextBox ID="txtProductName" runat="server"
Text='<%# Bind("ProductName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="單價">
<ItemTemplate>
<asp:TextBox ID="txtUnitPrice" runat="server"
Text='<%# Bind("UnitPrice", "{0:N2}") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="Discontinued" HeaderText="停產" />
<asp:TemplateField HeaderText="類別">
<ItemTemplate>
<asp:DropDownList ID="ddlCategory" runat="server"
DataSourceID="odsCategories" DataTextField="CategoryName"
DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void btnUpdateAll_Click(object sender, EventArgs e)
{
using (TransactionScope scope = new TransactionScope())
{
foreach (GridViewRow row in gvProducts.Rows)
{
// 取得控制項值
TextBox txtName = row.FindControl("txtProductName") as TextBox;
TextBox txtPrice = row.FindControl("txtUnitPrice") as TextBox;
DropDownList ddlCat = row.FindControl("ddlCategory") as DropDownList;
CheckBox chkDisc = row.FindControl("chkDiscontinued") as CheckBox;
int productID = (int)gvProducts.DataKeys[row.RowIndex].Value;
// 呼叫 BLL 更新 (需擴充接受所有欄位)
ProductsBLL.UpdateProduct(productID, txtName.Text,
decimal.Parse(txtPrice.Text), int.Parse(ddlCat.SelectedValue), chkDisc.Checked);
}
scope.Complete();
}
gvProducts.DataBind();
}
批次更新透過 TemplateField 實現全列編輯,配合事務確保資料一致性。適合後台管理、試算表式資料維護情境。