功能:
- 单击行弹出当前行详细页面
- 双击行进入编辑状态(GridView/DataGrid内置 Edit)
说明:
- 单击事件(onclick)使用了 setTimeout 延迟,根据实际需要修改延迟时间
- 常见处理行方式会选择在 RowDataBound/ItemDataBound 中处理,这里我选择 Page.Render 中处理,至少基于以下考虑
- RowDataBound 仅仅在调用 DataBind 之后才会触发,回发通过 ViewState 创建空件不触发 假如需要更多的处理,你需要分开部分逻辑到 RowCreated 等事件中
- 并且我们希望使用 ClientScript.GetPostBackEventReference 和 ClientScript.RegisterForEventValidation 方法 进行安全脚本的注册,而后者需要在页的 Render 阶段中才能处理
- 关于“DataGrid中采取的辅助按钮支持回发”见ASP.NET DEMO8: 为 GridView 每行添加服务器事件
- PS:未实现 Edit 对应的 Update/Cancel ,根据需要自行添加即可。
原始需求:既有单击又有双击的GridView是否存在(问了许多人都说不能,郁闷)可直接运行源码(单页 .aspx):
<% @ Page Language = " C# " %>
<% @ Import Namespace = " System.Data " %>
<%-- http: // community.youkuaiyun.com/Expert/TopicView3.asp?id=5767096--%>
<! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Transitional//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " >
< script runat = " server " >
protected void Page_Load( object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadGridViewProductData();
LoadDataGridProductData();
}
}
protected void GridView1_RowDataBound( object sender, GridViewRowEventArgs e)
{
/**//*
当然可以在这里进行客户端脚本绑定,
但是,我选择在重载页的 Render 方法中处理,因为
1. RowDataBound 仅仅在调用 DataBind 之后才会触发,回发通过 ViewState 创建空件不触发
假如需要更多的处理,你需要分开部分逻辑到 RowCreated 等事件中
2. 并且我们希望使用
ClientScript.GetPostBackEventReference 和 ClientScript.RegisterForEventValidation 方法
进行安全脚本的注册,而后者需要在页的 Render 阶段中才能处理
*/
}
protected void DataGrid1_ItemDataBound( object sender, DataGridItemEventArgs e)
{
// 隐藏辅助按钮列
int cellIndex = 0;
e.Item.Cells[cellIndex].Attributes["style"] = "display:none";
}
void LoadGridViewProductData()
{
DataTable dt = CreateSampleProductData();
GridView1.DataSource = dt;
GridView1.DataBind();
}
void LoadDataGridProductData()
{
DataTable dt = CreateSampleProductData();
DataGrid1.DataSource = dt;
DataGrid1.DataBind();
}
sample data #region sample data
static DataTable CreateSampleProductData()
{
DataTable tbl = new DataTable("Products");
tbl.Columns.Add("ProductID", typeof(int));
tbl.Columns.Add("ProductName", typeof(string));
tbl.Columns.Add("UnitPrice", typeof(decimal));
tbl.Columns.Add("CategoryID", typeof(int));
tbl.Rows.Add(1, "Chai", 18, 1);
tbl.Rows.Add(2, "Chang", 19, 1);
tbl.Rows.Add(3, "Aniseed Syrup", 10, 2);
tbl.Rows.Add(4, "Chef Anton's Cajun Seasoning", 22, 2);
tbl.Rows.Add(5, "Chef Anton's Gumbo Mix", 21.35, 2);
tbl.Rows.Add(47, "Zaanse koeken", 9.5, 3);
tbl.Rows.Add(48, "Chocolade", 12.75, 3);
tbl.Rows.Add(49, "Maxilaku", 20, 3);
return tbl;
}
#endregion
protected void GridView1_RowEditing( object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
LoadGridViewProductData();
}
protected void DataGrid1_EditCommand( object source, DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex = e.Item.ItemIndex;
LoadDataGridProductData();
}
protected override void Render(HtmlTextWriter writer)
{
// GridView
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowState == DataControlRowState.Edit)
{ // 编辑状态
row.Attributes.Remove("onclick");
row.Attributes.Remove("ondblclick");
row.Attributes.Remove("style");
row.Attributes["title"] = "编辑行";
continue;
}
if (row.RowType == DataControlRowType.DataRow)
{
//单击事件,为了响应双击事件,延迟 1 s,根据需要可能需要增加延迟
row.Attributes["onclick"] = String.Format("javascript:setTimeout(/"window.open('DummyProductDetail.aspx?productid={0}')/", 1000*1);event.cancelBubble=true;", GridView1.DataKeys[row.RowIndex].Value.ToString());
// 获取ASP.NET内置回发脚本函数,返回 __doPostBack(<<EventTarget>>, <<EventArgument>>)
// 可直接硬编码写入脚本,不推荐
row.Attributes["ondblclick"] = ClientScript.GetPostBackEventReference(GridView1, "Edit$" + row.RowIndex.ToString(), true);
//
row.Attributes["style"] = "cursor:pointer";
row.Attributes["title"] = "单击打开详细页面、双击进入编辑";
}
}
// DataGrid
foreach (DataGridItem item in DataGrid1.Items)
{
if (item.ItemType == ListItemType.EditItem)
{
item.Attributes.Remove("onclick");
item.Attributes.Remove("ondblclick");
item.Attributes.Remove("style");
item.Attributes["title"] = "编辑行";
continue;
}
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
//单击事件,为了响应双击事件,延迟 1 s,根据需要可能需要增加延迟
item.Attributes["onclick"] = String.Format("javascript:setTimeout(/"window.open('DummyProductDetail.aspx?productid={0}')/", 1000*1);event.cancelBubble=true;", DataGrid1.DataKeys[item.ItemIndex].ToString());
// 双击
// 获取辅助的支持回发按钮
// 相对而言, GridView 支持直接将 CommandName 作为 <<EventArgument>> 故不需要辅助按钮
Button btnHiddenPostButton = item.FindControl("btnHiddenPostButton") as Button;
// 获取ASP.NET内置回发脚本函数,返回 __doPostBack(<<EventTarget>>, <<EventArgument>>)
// 可直接硬编码写入脚本,不推荐
item.Attributes["ondblclick"] = ClientScript.GetPostBackEventReference(btnHiddenPostButton, "");
//
item.Attributes["style"] = "cursor:pointer";
item.Attributes["title"] = "单击打开详细页面、双击进入编辑";
}
}
base.Render(writer);
}
</ script >
< html xmlns = " http://www.w3.org/1999/xhtml " >
< head id = " Head1 " runat = " server " >
< title > ASP.NET DEMO15: GridView 行单击与双击事件 </ title >
</ head >
< body >
< form id = " form1 " runat = " server " >
< div >
< h3 > 功能: </ h3 >
< li > 单击弹出当前详细页面 </ li >
< li > 双击进入编辑状态(GridView / DataGrid内置 Edit) </ li >
< h3 > 说明: </ h3 >
< li > 单击事件(onclick)使用了 setTimeout 延迟,根据实际需要修改延迟时间 </ li >
< li > 常见处理行方式会选择在 RowDataBound / ItemDataBound 中处理,这里我选择 Page.Render 中处理,至少基于以下考虑
< li style = " padding-left:20px; list-style-type:square " > RowDataBound 仅仅在调用 DataBind 之后才会触发,回发通过 ViewState 创建空件不触发
假如需要更多的处理,你需要分开部分逻辑到 RowCreated 等事件中 </ li >
< li style = " padding-left:20px; list-style-type:square " > 并且我们希望使用
ClientScript.GetPostBackEventReference 和 ClientScript.RegisterForEventValidation 方法
进行安全脚本的注册,而后者需要在页的 Render 阶段中才能处理 </ li >
</ li >
< li > 关于“DataGrid中采取的辅助按钮支持回发”见 < a href = " http://www.cnblogs.com/Jinglecat/archive/2007/07/15/818394.html " > ASP.NET DEMO8: 为 GridView 每行添加服务器事件 </ a >
< br />
< input type = " button " id = " Button1 " value = " Rebind " onclick = " location.href=location.href; " />
< div style = " float:left " >
< h3 > GridView Version </ h3 >
< asp:GridView ID = " GridView1 " DataKeyNames = " ProductID " runat = " server " AutoGenerateColumns = " False " OnRowEditing = " GridView1_RowEditing " OnRowDataBound = " GridView1_RowDataBound " >
< Columns >
< asp:TemplateField HeaderText = " ProductName " >
< ItemTemplate >
<% # Eval( " ProductName " ) %>
</ ItemTemplate >
< EditItemTemplate >
< asp:TextBox ID = " txtProductName " runat = " server " Text = ' <%# Bind("ProductName") %> ' />
</ EditItemTemplate >
</ asp:TemplateField >
< asp:BoundField DataField = " UnitPrice " HeaderText = " UnitPrice " />
</ Columns >
</ asp:GridView ></ div >
< div style = " float:left;padding-left:100px; " >
< h3 > DataGrid Version </ h3 >
< asp:DataGrid ID = " DataGrid1 " DataKeyField = " ProductID " runat = " server " AutoGenerateColumns = " False " OnEditCommand = " DataGrid1_EditCommand " OnItemDataBound = " DataGrid1_ItemDataBound " >
< Columns >
< asp:TemplateColumn >
< ItemTemplate >
< asp:Button ID = " btnHiddenPostButton " CommandName = " Edit " runat = " server " Text = " HiddenPostButton " style = " display:none " />
</ ItemTemplate >
</ asp:TemplateColumn >
< asp:BoundColumn DataField = " ProductName " HeaderText = " ProductName " />
< asp:BoundColumn DataField = " UnitPrice " HeaderText = " UnitPrice " />
</ Columns >
</ asp:DataGrid ></ div >
</ li >
</ div >
</ form >
</ body >
</ html >
效果: