事件回顾
今天GridView翻页时,又遇到错误:索引超出范围。必须为非负值并小于集合大小。
这是当时的PageIndexChanging和RowCommand两个事件的后台代码
protected void GridViewResult_OnPageIndexChanging(object sender, GridViewPageEventArgs e) { GridViewResult.PageIndex = e.NewPageIndex; BindResults(); } protected void GridViewResult_OnRowCommand(object sender, GridViewCommandEventArgs e) { var index = Convert.ToInt32(GridViewResult.DataKeys[Convert.ToInt32(e.CommandArgument)].Value); if (e.CommandName == "ResultExcel") { var da = new DataClassesDataContext(); var daSelect = (from r in da.Results where r.Index == index select r).First(); CreateResultExcel(daSelect); Response.Redirect("FileDownload.aspx"); } else if(e.CommandName == "ResultDetail") { var da = new DataClassesDataContext(); var daSelect = (from r in da.Results where r.Index == index select r).First(); FillOutModal(daSelect); ScriptManager.RegisterStartupScript(this, GetType(), "ResultDetail", "OpenModalDefault();", true); } }
后经调试发现了一个一直被自己忽视的细节:点击GridView翻页按钮后,在引发PageIndexChanging事件前,先引发了RowCommand事件。
因为当时GridView翻到第二页后只有一行记录,而向前翻页(翻到第一页)的“1”按钮的e.CommandArgument=1
。
当这个1传递到RowCommand事件里面后,GridViewResult.DataKeys[1]
(第二行的主键)不存在,所以程序报错。
知道问题原因后,只需把获取index的语句移到if分支语句内部即可。
GridView中单击按钮,首先执行RowCommand事件
通过查阅MSDN,发现不但PageIndexChanging事件如此。
在单击GridView控件中的按钮时,将引发RowCommand事件。
而且可以通过设置CommandName属性,调用GridView的某些内置功能。
CommandName 值 | 描述 |
---|---|
“Cancel” | 取消编辑操作并将 GridView 控件返回为只读模式。引发 RowCancelingEdit 事件。 |
“Delete” | 删除当前记录。引发 RowDeleting 和 RowDeleted 事件。 |
“Edit” | 将当前记录置于编辑模式。引发 RowEditing 事件。 |
“Page” | 执行分页操作。将按钮的 CommandArgument 属性设置为“First”、“Last”、“Next”、“Prev”或页码,以指定要执行的分页操作类型。引发 PageIndexChanging 和 PageIndexChanged 事件。 |
“Select” | 选择当前记录。引发 SelectedIndexChanging 和 SelectedIndexChanged 事件。 |
“Sort” | 对 GridView 控件进行排序。引发 Sorting 和 Sorted 事件。 |
“Update” | 更新数据源中的当前记录。引发 RowUpdating 和 RowUpdated 事件。 |
尽管单击上表中所列出的按钮时将引发 RowCommand 事件,但仍建议您使用该表中列出的事件来执行该操作。
参考