使用gridview及其绑定,索引超出了范围问题

时间:2012-10-08 10:07:20

标签: c# asp.net exception gridview

我有一个包含500多条记录的网格。在第一页上,当我随机选择任何项目并点击编辑时,它会起作用,但在分页到任何页面之后它会给我异常

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

我已经交叉检查:启用了Viewstate,网格正确绑定。

以下是我的代码:

/// <summary>
/// Returns a comman separated value of the id selected in the grid.
/// </summary>
/// <param name="gv"></param>
/// <param name="checkbox"></param>
/// <returns></returns>
public static string GetGridViewsSelectedRowValues(GridView gv, string checkbox)
{
    var sb = new StringBuilder();
    if(gv.Rows.Count>0)
    {
        foreach (GridViewRow row in gv.Rows)
        {
            var cbx = (CheckBox) row.FindControl(checkbox);
            if(cbx!=null && cbx.Checked)
            {
                var dataKey = gv.DataKeys[row.RowIndex];
                if (dataKey != null) sb.Append(string.Format("{0},", dataKey.Value));
            }
        }
    }
    return sb.ToString().Remove(sb.ToString().LastIndexOf(','));
}

我点击了编辑按钮事件:

protected void btnEdit_Click(object sender, EventArgs e)
{
    int count = Common.GridSelectedRows(gvCityMaster, "chkBxSelect");
    if (count > 1)
    {
        Common.ShowMessage("Only one item can be edited at once.");
    }
    else
    {
        int id = Common.ParseInt(Common.GetGridViewsSelectedRowValues(gvCityMaster, "chkBxSelect"));
        if (id > 0)
        {
            DisplayForm();
            DisplayUserDetails(id);
        }
    }
}

我甚至研究过DataKeys Collection,它在每个系列中都有18个,这很好。

3 个答案:

答案 0 :(得分:0)

GridView.Rows仅返回当前页面的所有行。您可以使用ViewState在GridView中存储以逗号分隔的ID值。

private string SelectedIDs{
    get {
        if (ViewState("SelectedIDs") == null {
            ViewState("SelectedIDs") = "";
        }
        return (String)ViewState("SelectedIDs");
    }
    set { ViewState("SelectedIDs") = value; }
}

您需要更新PageIndexChanging中的字符串。

答案 1 :(得分:0)

上面的解决方案在分页时对我不起作用(使用C#.Net 4.5),所以我提出了另一个解决方案。

注意:我在选择时使行可编辑而不是按钮(第一个函数)。

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
    foreach (GridViewRow row in gridView.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
        {
            row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(gridView, "Select$" + row.DataItemIndex, true);
        }
    }
    base.Render(writer);
}

protected void trackingDataGV_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    gridView.PageIndex = e.NewPageIndex;
    getGridViewData();
}

protected void gridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "Select")
    {
        int pageSize = gridView.PageSize;
        int pageIndex = gridView.PageIndex;
        int rowIndex = Convert.ToInt32(e.CommandArgument);
        int newRowIndex = 0;

        if (pageIndex > 0)
        {
            newRowIndex = pageIndex * pageSize;
            rowIndex = rowIndex - newRowIndex;
        }

    string valueXYZ = ((HiddenField)gridView.Rows[rowIndex].FindControl("valueXYZ")).Value;
    }
}

答案 2 :(得分:0)

如果您在模板字段中有一个复选框:

<asp:GridView ID="EditListGridView" runat="server" AutoGenerateColumns="false"  AllowPaging="true" AllowSorting="true" PageSize="3" >
    <Columns>
      <asp:TemplateField>
        <ItemTemplate>
          <asp:CheckBox ID="Include" runat="server" OnCheckedChanged="Checkbox_Click"  AutoPostBack="true"  />
        </ItemTemplate>
      </asp:TemplateField>

要获取总索引,请使用:

int i = ((GridViewRow)((Control)sender).Parent.Parent).DataItemIndex;

要获取当前页面上的索引,请使用:

int i = ((GridViewRow)((Control)sender).Parent.Parent).RowIndex;

要获取分页gridview中的复选框(使用当前页面上的索引):

CheckBox cb = (CheckBox)EditListGridView.Rows[i].FindControl("Include");