代码改变世界

ASP.NET DEMO 16: 通过GridView布局实现的多行批量更新

2008-05-22 02:17 by 晓风残月, ... 阅读, ... 评论, 收藏, 编辑

 

特点:

  • 一次可批量提交多行数据
  • 客户端由CheckBox实现切换浏览/编辑状态,不需要回发
  • 服务器端实现维护编辑状态视图

源码下载

image

 

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%-- http://topic.csdn.net/u/20080521/15/a2da7051-4c1b-490d-ab28-1f01323aba47.html?seed=1952824859 --%>
<script runat="server">
void ShowProductData(GridView grid)
{
DataTable dt = CreateSampleData();
grid.DataSource = dt;
grid.DataBind();
}
#region sample data
static DataTable CreateSampleEmptyDataTable()
{
DataTable tbl = new DataTable("Student");
tbl.Columns.Add("StudentNO", typeof(string));
tbl.Columns.Add("FirstName", typeof(string));
tbl.Columns.Add("LastName", typeof(string));
tbl.Columns.Add("Age", typeof(int));
tbl.Columns.Add("Gender", typeof(string));
return tbl;
}
static DataTable CreateSampleData()
{
DataTable tbl = CreateSampleEmptyDataTable();
tbl.Rows.Add("20021342", "Jack", "Wu", 25, "M");
tbl.Rows.Add("20025341", "Jue", "You", 23, "F");
tbl.Rows.Add("20022254", "Viky", "Huang", 24, "F");
tbl.Rows.Add("20022231", "Leo", "Wong", 24, "M");
return tbl;
}
#endregion
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ShowProductData(GridView1);
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRowView drv = e.Row.DataItem as DataRowView;
// 同步ddlGender 选中项
if (drv != null)
{
DropDownList ddlGender = e.Row.FindControl("ddlGender") as DropDownList;
if (ddlGender != null)
{
ddlGender.SelectedValue = (string)drv["Gender"];
}
}
}
protected void GridView1_PreRender(object sender, EventArgs e)
{
// 维护客户端状态
bool b;
string m = "", n = "none";
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox chk = row.FindControl("chkEdit") as CheckBox;
//if (chk != null)
//{
b = chk.Checked;
// 以下代码未进行null 检查,确保存在对应ID的控件。
// 建立健壮性的程序,应进行非空引用检查。
//
(row.FindControl("lblFirstName") as WebControl).Style[HtmlTextWriterStyle.Display] = b ? n : m;
(row.FindControl("txtFirstName") as WebControl).Style[HtmlTextWriterStyle.Display] = b ? m : n;
//
(row.FindControl("lblLastName") as WebControl).Style[HtmlTextWriterStyle.Display] = b ? n : m;
(row.FindControl("txtLastName") as WebControl).Style[HtmlTextWriterStyle.Display] = b ? m : n;
//
(row.FindControl("lblAge") as WebControl).Style[HtmlTextWriterStyle.Display] = b ? n : m;
(row.FindControl("txtAge") as WebControl).Style[HtmlTextWriterStyle.Display] = b ? m : n;
//
(row.FindControl("lblGender") as WebControl).Style[HtmlTextWriterStyle.Display] = b ? n : m;
(row.FindControl("ddlGender") as WebControl).Style[HtmlTextWriterStyle.Display] = b ? m : n;
//}
}
}
protected void btnUpdate_Click(object sender, EventArgs e)
{
bool updated = false;
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox chk = row.FindControl("chkEdit") as CheckBox;
if (chk != null && chk.Checked)
{
// 以下代码未进行null 检查,确保存在对应ID的控件
// 建立健壮性的程序,应进行非空引用检查。
string newFirstName = (row.FindControl("txtFirstName") as TextBox).Text.Trim();
string newLastName = (row.FindControl("txtLastName") as TextBox).Text.Trim();
int newAge = int.Parse((row.FindControl("txtAge") as TextBox).Text.Trim());
string newGender = (row.FindControl("ddlGender") as DropDownList).SelectedValue;
//******************************************************************************************/
// 这里执行真正的数据库更新操作
// ....
Response.Write("<script>alert('请在[btnUpdate_Click(object sender, EventArgs e)]中实现自己的数据库更新代码')<" + "/script>");
// ....
//******************************************************************************************/
updated = true;
}
}
//// 假如有数据更新,从数据库加载新数据刷新页面
//// 当然如果很在乎性能,可以直接从TextBox 的值copy 到Label,但实现起来费时。
//if (updated)
//{
//    ShowProductData();
//}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>ASP.NET DEMO16_GridViewBatchEdit</title>
<script type="text/javascript">
var $ = function(id) { return document.getElementById(id); }
function chkEdit_Click(sender, args)
{
//debugger;
// 切换可编辑状态
var b = sender.checked;
var m = "", n = "none";
//
$(args.containerClientID + "_" + "lblFirstName").style.display = b ? n : m;
$(args.containerClientID + "_" + "txtFirstName").style.display = b ? m : n;;
//
$(args.containerClientID + "_" + "lblLastName").style.display = b ? n : m;
$(args.containerClientID + "_" + "txtLastName").style.display = b ? m : n;;
//
$(args.containerClientID + "_" + "lblAge").style.display = b ? n : m;
$(args.containerClientID + "_" + "txtAge").style.display = b ? m : n;;
//
$(args.containerClientID + "_" + "lblAge").style.display = b ? n : m;
$(args.containerClientID + "_" + "txtAge").style.display = b ? m : n;;
//
$(args.containerClientID + "_" + "lblGender").style.display = b ? n : m;
$(args.containerClientID + "_" + "ddlGender").style.display = b ? m : n;;
}
function shouldUpdate()
{
var grd = $('<% =GridView1.ClientID %>');
var inputs = grd.getElementsByTagName('input');
for(var i = 0; i < inputs.length; i++) {
if(inputs[i].type == "checkbox" && inputs[i].id.indexOf("chkEdit") > 0 && inputs[i].checked) {
return true;
}
}
return false;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h3>通过GridView布局实现的批量更新</h3>
<em>请在[btnUpdate_Click(object sender, EventArgs e)]中实现自己的数据库更新代码</em>
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="GridView1_RowDataBound" OnPreRender="GridView1_PreRender">
<Columns>
<asp:TemplateField HeaderText="Edit?">
<ItemTemplate>
<asp:CheckBox id="chkEdit" onclick='<%# String.Format(@"chkEdit_Click(this, {{containerClientID:""{0}""}})", (Container as Control).ClientID) %>'
ToolTip="Enable Edit?" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="StudentNO">
<ItemTemplate>
<%# (Container.DataItem as DataRowView)["StudentNO"]%> <!-- 避免反射,可提升性能-->
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="FirstName">
<ItemTemplate>
<asp:Label ID="lblFirstName" runat="server" Text='<%# (Container.DataItem as DataRowView)["FirstName"] %>' />
<asp:Textbox ID="txtFirstName" runat="server" Text='<%# ((Container as Control).FindControl("lblFirstName") as Label).Text %>' style="display:none;" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="LastName">
<ItemTemplate>
<asp:Label ID="lblLastName" runat="server" Text='<%# Eval("LastName") %>' />
<asp:Textbox ID="txtLastName" runat="server" Text='<%# ((Container as Control).FindControl("lblLastName") as Label).Text %>' style="display:none;" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Age">
<ItemTemplate>
<asp:Label ID="lblAge" runat="server" Text='<%# Eval("Age") %>' />
<asp:Textbox ID="txtAge" runat="server" Text='<%# ((Container as Control).FindControl("lblAge") as Label).Text %>' style="display:none;" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Gender">
<ItemTemplate>
<asp:Label ID="lblGender" runat="server" Text='<%# Eval("Gender").ToString() == "M" ? "Male" : "Female" %>' />
<asp:DropDownList ID="ddlGender" runat="server" style="display:none">
<asp:ListItem Value="M" Text="Male"/>
<asp:ListItem Value="F" Text="Female"/>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<input id="Button2" type="button" value="Reload" onclick="location.href=location.href;" />
<asp:Button ID="btnUpdate" runat="server" Text="Update" OnClick="btnUpdate_Click" OnClientClick="if(!shouldUpdate()) return !!alert('没有可更新数据!');" />
</div>
</form>
</body>
</html>

 

其他可用方案

一次编辑 GridView 的所有行 (孟老大)