ASP.Net:DataPager控件在分页时始终滞后一步

26

以下是一个示例... 一个页面包含 ListView 和用于分页 ListView 数据的 DataPager:

代码后台:

protected void Page_Load(object sender, EventArgs e)
{
    MyList.DataSource = GetSomeList();
    MyList.DataBind();
}

Source:

<asp:ListView ID="MyList" runat="server">
    <% //LayoutTemplate and ItemTemplate removed for the example %>
</asp:ListView>

<asp:DataPager ID="ListPager" PagedControlID="MyList" runat="server" PageSize="10">
    <Fields>
        <asp:NumericPagerField  />
    </Fields>
</asp:DataPager>
DataPager存在的问题是在绑定时总是比实际操作慢一步。例如,当页面加载时,它在第一页。然后当您单击第3页时,在回传后仍停留在第1页。接着你单击第5页,在回传后发现自己在第3页...然后你再单击第6页,它会发现自己在第5页...以此类推。为什么分页没有按预期工作呢?
6个回答

35

解决方案

问题是由于绑定发生在Page_Load事件上。

为了使其按预期工作,绑定需要在DataPagerOnPreRender事件中发生,而不是在Page_Load中。

来源:

<asp:DataPager ID="ListPager" PagedControlID="MyList" runat="server" PageSize="10"
    OnPreRender="ListPager_PreRender">

<Fields>
        <asp:NumericPagerField  />
    </Fields>
</asp:DataPager>

代码后台:

protected void Page_Load(object sender, EventArgs e)
{
    //Binding code moved from Page_Load
    //to the ListView's PreRender event
}

protected void ListPager_PreRender(object sender, EventArgs e)
{
    MyList.DataSource = GetSomeList();
    MyList.DataBind();    
}

4
谢谢!这是另一个未被充分记录的 ASP.net 怪癖。 - Dexter

6
我遇到了相同的问题,但是每次在datapager prerender上绑定并不适用于我。相反,我能够通过仅在分页发生时绑定来完成同样的事情。这个解决方案可以作为Andreas prerender解决方案的替代方法。以下对我有用:
通过附加到ListView的PagePropertiesChanged事件,我能够纠正分页问题,而无需在数据分页程序的每个prerender上进行绑定。
注意:大多数数据分页器属性都设置在皮肤文件中,这就是为什么它们不在标记中的原因。
标记:
<asp:DataPager ID="ListPager" runat="server" PagedControlID="MyList" />
<asp:ListView ID="MyList" runat="server">
    <% //LayoutTemplate and ItemTemplate removed for the example %>
</asp:ListView>

后台代码:

protected void Page_Load(object sender, EventArgs e) {
   MyList.PagePropertiesChanged += new EventHandler(MyList_PagePropertiesChanged);
}

/// <summary>
/// Handles the situation where the page properties have changed.  Rebind the data
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MyList_PagePropertiesChanged(object sender, EventArgs e) {
   MyList.DataSource = GetSomeList();
   MyList.DataBind();
}

你的方法是否也适用于另一个控件的PostBack事件,该事件会导致ListView呈现默认绑定(null)?如果是这样,我将在我的项目中使用你的方法。 - Myra
我自己还没有测试过。据我所知,PagePropertiesChanged事件仅在分页更改时触发,而不一定在每个postback上都触发。如果另一个控件进行了postback,您可能需要在该其他控件的事件处理程序中重新绑定。您必须尝试并查看。 - Jay S
我认为这是正确的答案。为什么我们应该在每个请求中获取一个源(来自数据库)?毫无意义。 - Txugo

1

您的Datapager缺少OnPreRender事件!


0

或者,如果您正在构建仅包含ListView的用户控件,则可以将分页器事件处理程序简单地指向Page_Load方法,因为Page_Load方法不会运行其他任何内容:

<asp:DataPager ID="ListPager" PagedControlID="MyList" runat="server" PageSize="10"
OnPreRender="Page_Load">

0

以下方法对我来说完美运作。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles   Me.Load
Dim ds As DataSet
ds = SQLHELPER.ExecuteDataSet(CommandType.StoredProcedure, "sp_Locations")
rs.EnableViewState = False
rs.DataSource = ds
rs.DataBind()
End Sub

Protected Sub rs_PagePropertiesChanging(ByVal sender As Object, ByVal e As    PagePropertiesChangingEventArgs)
'set current page startindex, max rows and rebind to false
Pager.SetPageProperties(e.StartRowIndex, e.MaximumRows, False)
'rebind List View
rs.DataBind()
End Sub

<asp:ListView ID="rs" runat="server" onpagepropertieschanging="rs_PagePropertiesChanging">

-2
在页面加载中,您应该将代码放置在以下代码块之间:
if (!IsPostBack) { }
这将解决您的问题。

2
只是指出给其他盲目跟随的可怜人 - 这不会解决问题。请参见下面的正确答案。 - George

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