GridView 分页问题

3

我正在使用一个GridView控件,并手动进行分页和排序。 下面是分页的方法:

protected void gdvMainList_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        gdvMainList.PageIndex = e.NewPageIndex;
        gdvMainList.DataSource = dtConsentReleaseList;
        gdvMainList.DataBind();
    }

我有一个静态数据表,其中有一列Id:

dtConsentReleaseList.Columns.Add("Id");
            dtConsentReleaseList.Columns.Add("StartDate");
            dtConsentReleaseList.Columns.Add("EndDate");
            dtConsentReleaseList.Columns.Add("Contact");

我在GridView中分配了数据关键字“Id”。 每一行都有一个打印按钮。当我点击该按钮时,执行以下代码:

else if (e.CommandName == "New")
        {                
            int selectedIndex = Convert.ToInt32(e.CommandArgument);
            int consentReleaseId = Convert.ToInt32(gdvMainList.DataKeys[selectedIndex].Value);
            string openReportScript = Utility.OpenReport(ResolveClientUrl("~/Reports/Consumer/ConsentReleaseReport.aspx?Id=" + consentReleaseId + "&ReportTitle=ConsentForRelease"));
            ScriptManager.RegisterClientScriptBlock(upConsentRelease, upConsentRelease.GetType(), "Pop up", openReportScript, true);
        }

但是当我切换页面并点击打印按钮时,该行代码会出现异常:
int consentReleaseId = Convert.ToInt32(gdvMainList.DataKeys[selectedIndex].Value);

异常是:

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

我猜在分页方法中我做错了什么。请帮帮我吧?
3个回答

1

您正在尝试根据任意ID而不是实际索引从数组中获取值。但您根本不需要这样做。您不需要将ID存储在DataKeys中,也不需要使用项目的索引访问任何内容。只需从CommandArgument中提取您的ID即可。

<asp:ImageButton CommandName="New" CommandArgument='<%# Eval("Id") %>' ID="ibtnPrint" runat="server" ImageUrl="~/App_Themes/Default/images/print.png" />

然后在代码后台:

int consentReleaseId = int.Parse(e.CommandArgument);

我的“e”中没有e.Item.ItemIndex,因为我正在使用此方法:protected void gdvMainList_RowCommand(object sender, GridViewCommandEventArgs e)。 - asma
我猜它不会做任何事情,因为我的代码在网格的第一页完美运行。问题出现在下一页... - asma
动动脑筋,我现在没有打开任何ASP.NET项目。我只是建议你向你用来引起后台事件的任何控件(比如 "打印"按钮)添加“CommandArgument”属性,并将该属性的值设置为“<%# Eval ("Id")%>”。 - Josh M.
就像我之前说过的那样,多次强调,你不需要索引。你只需要ID,对吧?所以把你的代码改成这样:CommandArgument='<%# Eval("Id") %>' 来存储ID而不是索引。 - Josh M.
非常感谢Josh M.,他解决了我的问题。你是101%正确的!再次感谢... :-) - asma
显示剩余5条评论

0
我的猜想是您在代码后端(可能是Page_Load事件)绑定了GridView,但是它在回传时不保留值。
此外,请尝试将Id作为CommandArgument传递。据我所知,如果您可以访问所选记录的Id,则根本不需要Grid的行索引。(GridView默认通过CommandArgument传递行索引)

最终的问题是我在网格的下一页上没有得到ID。你有什么想法,下一页发生了什么? - asma
我也在gdvMainList_PageIndexChanging方法中绑定了网格。但是Bt Id不可用。 - asma
我猜这就是我提到的postback问题。一旦我为gridview实现了自定义分页,但我忽略了内置分页(我几乎可以肯定你最终会得到这样的解决方案)。我使用了一个很棒的自定义控件来自http://www.codeproject.com/KB/custom-controls/ASPNETPagerControl.aspx。 - Kamyar

0
在绑定 GridView 之前,先将 DataKeyName 设置为正确的值,并且设置数据源。
此外,
string[] dk = new string[1] {"MyID"};
myGridView.DataKeyNames = dk;
myGridView.DataSource = ds;
myGridView.DataBind();

@asma - 抱歉,请尝试使用 string[] dk = new string[1] { "MyID" }; - JonH
问题仍然存在。当我点击打印按钮时,它无法获取数据键名。 - asma
@asma - 你需要发布更多的代码,你在哪里进行DataBinding()操作?这可能与asp.net页面生命周期处理所有这些的方式有关。RowCommand处理程序甚至在触发page_load之前就已经运行了。确保网格视图已经绑定,然后再开始浏览数据集。另外,你是否启用了网格视图上的ViewState? - JonH
我认为你的解决方案与@asma所描述的问题无关。你只需要设置DataKeyNames属性一次,然后就可以随意重新绑定GridView了。 - Josh M.
@JonH:我的网格中没有使用EnableViewState。 - asma
@asma为什么不用它?打开它。 - JonH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接