在.NET中使用GridView控件的在线编辑数据时,出现了“ Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index"的关于数据索引值错误的问题,在网上查了许多,感觉都没有什么文章是直接指出解决问题的方法,先就总结下吧
其实,这个问题在操作时是需要非常注意的,它并不在GridView控件的RowEditing或者RowUpdating方法中,而是需要在获取数据的类中指定GridView控件的主键,后台代码如部分如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Data; 8 using System.Data.SqlClient; 9 using System.Configuration; 10 11 namespace UI 12 { 13 public partial class _Default : System.Web.UI.Page 14 { 15 protected void Page_Load(object sender, EventArgs e) 16 { 17 //判断是否第一次加载Bind()类 18 if (!IsPostBack) 19 { 20 Bind(); 21 } 22 } 23 24 /// <summary>创建返回数据库连接的公共类 25 /// </summary> 26 /// <returns>返回连接数据库的类</returns> 27 public SqlConnection GetConnection() 28 { 29 string str_conn = ConfigurationManager.AppSettings["myConStr"].ToString(); 30 SqlConnection myConn = new SqlConnection(str_conn); 31 return myConn; 32 } 33 34 /// <summary>将查询的数据绑定到GridView控件中 35 /// </summary> 36 public void Bind() 37 { 38 try 39 { 40 SqlConnection myConn = GetConnection(); 41 myConn.Open(); 42 43 string sql_Str = "select * from stuInfo order by stuAge desc"; 44 45 SqlDataAdapter myda = new SqlDataAdapter(sql_Str, myConn); 46 DataSet myDs = new DataSet(); 47 myda.Fill(myDs); 48 49 GridView1.DataSource = myDs; 50 51 //为GridView控件设置主键,此处必须有否则会产生如下代码中的溢出错误 52 /* 53 * Index was out of range. Must be non-negative and less than the size of the collection. 54 Parameter name: index 55 */ 56 GridView1.DataKeyNames = new string[] { "stuNo" };//GridView控件设置主键,此处最为关键,稍不留意就忘掉了,切记呀 57 GridView1.DataBind(); 58 59 myDs.Dispose(); 60 myda.Dispose(); 61 myConn.Close(); 62 } 63 catch (Exception ex) 64 { 65 Response.Write(ex.Message); 66 } 67 } 68 69 /// <summary>创建GridView控件的RowEditing事件类 70 /// </summary> 71 /// <param name="sender"></param> 72 /// <param name="e"></param> 73 protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e) 74 { 75 GridView1.EditIndex = e.NewEditIndex; 76 this.Bind(); 77 } 78 79 /// <summary>创建GridView控件的RowUpdating事件类 80 /// </summary> 81 /// <param name="sender"></param> 82 /// <param name="e"></param> 83 protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e) 84 { 85 try 86 { 87 //获取在GridView控件里相关事件的键值 88 int stuNum = Convert.ToInt32(GridView1.DataKeys[e.RowIndex].Value.ToString()); 89 string newName = ((TextBox)(GridView1.Rows[e.RowIndex].Cells[1].Controls[0])).Text.ToString(); 90 91 SqlConnection myConn = GetConnection(); 92 myConn.Open(); 93 94 /* 95 * string sql_str = "update stuInfo set stuName='" + newName + "' where stuNo='" + stuNum + "'"; 96 *与上句相比,以下使用带参数的SQL语句在一定程度上可防止SQL注入攻击 97 */ 98 string sql_str = "update stuInfo set stuName=@newName where stuNo=@stuNum"; 99 SqlCommand myCmd = new SqlCommand(sql_str, myConn); 100 myCmd.Parameters.Add("@newName", SqlDbType.NVarChar).Value = newName; 101 myCmd.Parameters.Add("@stuNum", SqlDbType.VarChar).Value = stuNum; 102 103 if (myCmd.ExecuteNonQuery() > 0) 104 { 105 Response.Write("<script type='text/javascript'>alert('更新成功');</script>"); 106 } 107 else 108 { 109 Response.Write("<script type='text/javascript'>alert('更新失败');</script>"); 110 } 111 112 //调试用 113 textbox1.Text = "学号:" + stuNum + " , 姓名:" + newName + ", " + sql_str + ", ExecuteNonQuery状态:" + myCmd.ExecuteNonQuery(); 114 115 myCmd.Dispose(); 116 myConn.Close(); 117 GridView1.EditIndex = -1; 118 this.Bind(); 119 } 120 catch (Exception ex) 121 { 122 Response.Write(ex.Message); 123 } 124 } 125 126 /// <summary>创建GridView控件的RowCancelingEdit事件类 127 /// </summary> 128 /// <param name="sender"></param> 129 /// <param name="e"></param> 130 protected void GridView1_RowsCancelingEdit(object sender, GridViewCancelEditEventArgs e) 131 { 132 GridView1.EditIndex = -1; 133 this.Bind(); 134 }
135 }
136 }
至于前台页面,无非就是绑定相关的事件了,在这就不贴代码了