2012-02-29 219 views
0

我正在使用一个网站,用户可以从列表中添加和删除视频。
所有添加和删除都是通过复选框完成的。我可以一次添加多个视频,但是当我试图删除它们的多个在从列表中时,它给了我这个错误:“索引超出范围...”错误

Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

然而,当没有任何问题,在删除一个一次。另外,当我得到错误,并返回检查视频消失。
这是在C#ASP.NET中,我不知道错误在哪里,但我相信它是在btnDeleteVideo_Click事件。如果需要,我将显示其他事件(btnAddVideo_Click)作为参考。如果它有帮助,我可以删除它。我是新来的stackoverflow,所以我很抱歉,如果这是太多或太少的信息。

下面是两个添加和删除事件的代码:

protected void btnAddVideo_Click(object sender, EventArgs e) 
{ 

    foreach (GridViewRow gvr in GridView3.Rows) 
    { 
     CheckBox chkItem = (CheckBox)gvr.FindControl("cbAdd"); 
     if (chkItem.Checked) 

     { 
      String sRecID = GridView3.DataKeys[gvr.RowIndex].Value.ToString(); 
      Session["videorecid"] = sRecID; 
      SqlDataSource2.Insert(); 
      SqlDataSource2.SelectCommand = "SELECT * FROM dealervideo inner join videos on videos.RecID = dealervideo.VideoRecID inner join dealers on dealers.RecID = dealervideo.DealerRecID where dealers.RecID = " + hidRecID.Value; 
      GridView2.DataBind(); 
     } 
    } 
    GridView2.DataBind(); 
} 

protected void btnDeleteVideo_Click(object sender, EventArgs e) 
{ 

    foreach (GridViewRow gvr in GridView2.Rows) 
    { 
     CheckBox chkItem = (CheckBox)gvr.FindControl("cbDelete"); 
     if (chkItem.Checked) 
     { 
      String sRecID = GridView2.DataKeys[gvr.RowIndex].Value.ToString(); 
      Session["videorecid"] = sRecID; 
      SqlDataSource2.Delete(); 
      SqlDataSource2.SelectCommand = "SELECT * FROM dealervideo inner join videos on videos.RecID = dealervideo.VideoRecID inner join dealers on dealers.RecID = dealervideo.DealerRecID where dealers.RecID = " + hidRecID.Value; 
      GridView2.DataBind(); 
     } 
    } 
} 
+0

是不是因为所有的后者的指数变化后的检查框第一个被删除,然后再次,然后再次。 – ediblecode 2012-02-29 17:14:07

+0

我会添加一些调试信息,以查看代码失败的确切位置。我猜'gvr。RowIndex'有时是负面的,所以也许你应该打印出来(或者一步步穿过它) – sebagomez 2012-02-29 17:14:10

+0

感谢您清除问题,我不知道该怎么做,我为此道歉。 – Peter 2012-02-29 17:31:12

回答

2

问题是btnDeleteVideo_Click的逻辑。

想象一下,您的列表中有5个项目,编号为0到4,并且您尝试一次删除2个项目。

上面的代码现在遍历所有五行。当它到达第一次删除时,它将通过从数据源中删除和重新绑定来删除一行。

它现在继续循环,直到找到从删除标记的第二个项目 - 除了您的网格现在包含一个较少的行,因为您已删除并反弹。

因此,线路String sRecID = GridView2.DataKeys[gvr.RowIndex].Value.ToString();将具有爆炸的趋势,因为原始RowIndex现在可能高于实际行数。

更好的方法是按照你的方式计算出你想要通过loopin删除的所有行,但是只能在最后删除并重新绑定。

-2

如果我是正确的......你可以先尝试铸造的复选框的索引值。作为也许值是一个字符串,如果你的索引数组可能会造成一个问题,一个字符串值..

这条线:

String sRecID = GridView3.DataKeys[gvr.RowIndex].Value.ToString(); Session["videorecid"] = sRecID;

gvr.Rowindex尝试将其转换为整数...第一

0

您在每次删除后重新绑定您的网格,这会将行数减少一个 - 删除所有内容然后重新绑定。

0

我建议移动

SqlDataSource2.SelectCommand = "SELECT * FROM dealervideo inner join videos on videos.RecID = dealervideo.VideoRecID inner join dealers on dealers.RecID = dealervideo.DealerRecID where dealers.RecID = " + hidRecID.Value; 
GridView2.DataBind(); 

外的foreach循环。

2

不要调用foreach循环内GridView2.DataBind();,这样做只是一个时间结束(就像你已经这样做)

+0

它就像绑定在循环外面一样简单,哇。谢谢! – Peter 2012-02-29 17:38:28