让你的GridView、DataList 的数据行同时具有单击或双击选中的功能
Note:
英文原文链接:http://www.codeproject.com/KB/webforms/DoubleClickGridviewRow.aspx
网上有很多方法不仅可以实现在GridView的一行的任意位置单击实现选中功能,而且也可以实现双击选中的功能。但我还没有遇到过能同时具有单击和双击功能,并且可以很好的解决event validation errors 。
这里,我将给出一种可以在ASP.NET2.0下同时实现行的单/双击选中行的方法,其适用范围有 GridView
, DataList ,
ListBox等控件。
背景:
当开发一个ASP.NET的应用程序去代替传统的Windows应用程序,经常被要去使其用户体验接近于传统模式。传统的应用程序允许用户选中工具栏中的行,并执行其事件响应。通过点击一行,可以打开另一个Form,并看到其细节。这种功能可以很容易的通过在GridView中设置两个隐藏的ButtonField去实现,当然我要做的比这样更好。
可单/双击的GridView
创建一个Web应用程序,其默认页面为Default.aspx. 现在, 事
EnableEventValidation="false"
. 我们以后再移除它.添加一个 GridView并绑定数据源
. 在GridVIew上点击-编辑列-添加两个 asp:ButtonField
. 分别为其命名为 SingleClick和
DoubleClick
.
- <Columns>
- <asp:ButtonField Text="SingleClick" CommandName="SingleClick" />
- <asp:ButtonField Text="DoubleClick" CommandName="DoubleClick" />
- </Columns>
添加GridView的
RowCommand事件,并用Switch语句去捕获其选中事件。下面的示例将在页面显示你所选中过GridView行的索引列表。
- protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
- {
- GridView _gridView = (GridView)sender;
- // Get the selected index and the command name
- int _selectedIndex = int.Parse(e.CommandArgument.ToString());
- string _commandName = e.CommandName;
- switch (_commandName)
- {
- case ("SingleClick"):
- _gridView.SelectedIndex = _selectedIndex;
- this.Message.Text += "Single clicked GridView row at index "
- + _selectedIndex.ToString() + "<br />";
- break;
- case ("DoubleClick"):
- this.Message.Text += "Double clicked GridView row at index "
- + _selectedIndex.ToString() + "<br />";
- break;
- }
- }
添加
RowDataBound 事件在绑定数据时修改每一行的属性。现在,我们需要为每一行添加客户端脚本(即添加onclick),该脚本作用于SingleClick按钮。
- if (e.Row.RowType == DataControlRowType.DataRow)
- {
- // Get the LinkButton control in the first cell
- LinkButton _singleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];
- // Get the javascript which is assigned to this LinkButton
- string _jsSingle =
- ClientScript.GetPostBackClientHyperlink(_singleClickButton, "");
- // Add this javascript to the onclick Attribute of the row
- e.Row.Attributes["onclick"] = _jsSingle;
- }
同理,我们可以对DoubleClick按钮做同样操作,但两者不会同时起作用。
- if (e.Row.RowType == DataControlRowType.DataRow)
- {
- // Get the LinkButton control in the second cell
- LinkButton _doubleClickButton = (LinkButton)e.Row.Cells[1].Controls[0];
- // Get the javascript which is assigned to this LinkButton
- string _jsDouble =
- ClientScript.GetPostBackClientHyperlink(_doubleClickButton, "");
- // Add this JavaScript to the ondblclick Attribute of the row
- e.Row.Attributes["ondblclick"] = _jsDouble;
- }
- onclick="javascript:__doPostBack('GridView1$ctl02$ctl00','')"
将超时设置为300毫秒
- onclick="javascript:setTimeout
- ("__doPostBack('GridView1$ctl02$ctl00','')", 300)"
完整的DataRowBound的代码如下:
- protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
- {
- if (e.Row.RowType == DataControlRowType.DataRow)
- {
- // Get the LinkButton control in the first cell
- LinkButton _singleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];
- // Get the javascript which is assigned to this LinkButton
- string _jsSingle =
- ClientScript.GetPostBackClientHyperlink(_singleClickButton, "");
- // To prevent the first click from posting back immediately
- // (therefore giving the user a chance to double click)
- // pause the postbackfor 300 milliseconds by
- // wrapping the postback command in a setTimeout
- _jsSingle = _jsSingle.Insert(11, "setTimeout(\"");
- _jsSingle += "\", 300)";
- // Add this javascript to the onclick Attribute of the row
- e.Row.Attributes["onclick"] = _jsSingle;
- // Get the LinkButton control in the second cell
- LinkButton _doubleClickButton = (LinkButton)e.Row.Cells[1].Controls[0];
- // Get the javascript which is assigned to this LinkButton
- string _jsDouble =
- ClientScript.GetPostBackClientHyperlink(_doubleClickButton, "");
- // Add this javascript to the ondblclick Attribute of the row
- e.Row.Attributes["ondblclick"] = _jsDouble;
- }
- }
此时,这两个按钮应该设置为隐藏
- <Columns>
- <asp:ButtonField Text="SingleClick" CommandName="SingleClick"
- Visible="false" />
- <asp:ButtonField Text="DoubleClick" CommandName="DoubleClick"
- Visible="false" />
- </Columns>
现在,RowCommand可以同时捕捉到GridView一行的单双击事件了。
注册用以验证的postback 和callback数据
一切都运行的很好,请别忘记一开始我们设置了 EnableEventValidation="false" ,这不是安全的选项,我们要移除它。这在单击时将导致出现"Invalid postback or callback argument" 错误。这个错误告诉我们去使用theClientScriptManager.RegisterForEventValidation 去注册postback或callback数据。
ClientScriptManager.RegisterForEventValidation可以被重载的Render方法调用。这里的关键是注册GridView一行的两个按钮个unique Id。每一行的UniqueID被转换为GridView.UniqueID,第一个按钮的UniqueID仅需要在GridView.UniqueId的后面就附加上”$ctl00“,第二个按钮则附加上 "$ctl01".
- protected override void Render(HtmlTextWriter writer)
- {
- foreach (GridViewRow r in GridView1.Rows)
- {
- if (r.RowType == DataControlRowType.DataRow)
- {
- Page.ClientScript.RegisterForEventValidation
- (r.UniqueID + "$ctl00");
- Page.ClientScript.RegisterForEventValidation
- (r.UniqueID + "$ctl01");
- }
- }
- base.Render(writer);
- }
现在将不会出现任何“invalid postback or callback argument”错误了。
结论
通过JS与ASP.NET的紧密结合,我们可以扩展GridView和DataList的功能。为了你的程序的安全,如果可以的话,你不应该将EnableEventValidation="false"
。一旦你理解了EventValidation是如何工作的,你可以使用ClientScript.RegisterForEventValidation却包你的代码执行的更安全
url:http://greatverve.cnblogs.com/archive/2011/12/19/gridview-datalist-click-doubleclick.html
我这个博客废弃不用了,今天想寻找外链的时候,突然想到这个博客权重很高。
有需要免费外链的,留言即可,我准备把这个博客变成免费的友情链接站点。