“索引超出范围......”错误

时间:2012-02-29 17:06:58

标签: c# asp.net gridview

我正在开发一个网站,用户可以在列表中添加和删除视频 所有添加和删除都使用复选框完成。我可以一次添加多个视频,但当我尝试从列表中一次删除多个视频时,它会给我这个错误:

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();
        }
    }
}

5 个答案:

答案 0 :(得分:2)

问题是btnDeleteVideo_Click的逻辑。

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

上面的代码现在循环遍历所有五行。当它进入第一次删除时,它会通过从数据源中删除并重新绑定来删除一行。

它现在继续循环,直到它找到第二个标记为删除的项目 - 除了你的网格现在包含自删除和反弹以来少一行。

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

更好的方法是按原样通过loopin计算出要删除的所有行,但最后只删除并重新绑定。

答案 1 :(得分:2)

不要在foreach循环中调用GridView2.DataBind();,最后只执行一次(就像你已经在做的那样)

答案 2 :(得分:0)

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

答案 3 :(得分: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循环之外。

答案 4 :(得分:-2)

如果我是正确的......您可以先尝试转换复选框索引值..因为该值可能是一个字符串,如果您在数组中索引字符串值可能会产生问题..

这一行:

  

String sRecID = GridView3.DataKeys [gvr.RowIndex] .Value.ToString();               会话[“videorecid”] = sRecID;

gvr.Rowindex尝试将其转换为整数...首先