After eight (well, seven.. lunch) torturous hours, trying to figure out something so simple, that should have been so easy, I’m finally done. (Spoiler: skip to the bottom to figure out how to fix the paging-control-one-step-behind issue)
My scenario: I had an IList of objects, populated via some nHibernate magic. How I got the data isn’t the important thing; just mattered that I had an IList of some object that I needed to put into some kind of paged display. The tricky bit was doing it through the codebehind, rather than setting up an ObjectDataSource for it. I tried several different methods, but kept coming back to one solution: a ListView with the new DataPager control.
It should have been pretty easy; the the DataPager control isn’t terribly hard to set up. Just throw in the control, populate the ID, runat, pagesize, and pagedcontrolid (the control that it adds paging to). That was attached to a listview, with an id and runat, and it had a layout template, item template, and alternatingtemplate inside of it. It all looked something like:
<asp:DataPager ID=”dpDataPager”
runat=”server”
PageSize=”5″
PagedControlID=”lvItems”>
<Fields>
<asp:NextPreviousPagerField NextPageText=”next »” ShowFirstPageButton=”true” ShowLastPageButton=”false” ShowNextPageButton=”false” ShowPreviousPageButton=”true” />
<asp:NumericPagerField ButtonCount=”10″/>
<asp:NextPreviousPagerField PreviousPageText=”« previous” ShowFirstPageButton=”false” ShowLastPageButton=”true” ShowNextPageButton=”true” ShowPreviousPageButton=”false” />
</Fields>
</asp:DataPager>
<asp:ListView ID=”lvItems”
runat=”server”>
<LayoutTemplate>
<span id=”itemPlaceholder” runat=”server”></span>
</LayoutTemplate>
<ItemTemplate>
<li class=”even”><%# Eval(“Caption”) %></li>
</ItemTemplate>
<AlternatingItemTemplate>
<li class=”odd”><%#
Eval(“Caption”) %></li>
</AlternatingItemTemplate>
</asp:ListView>
And (the important bits) in my code behind:
In the Page_Load, I had
if
(!IsPostBack)
{
bind();
}
And after the Page_Load method, I had
private void bind()
{
IList<Content> content;
int id = Int32.Parse(Request.QueryString["id"]);
FeatureValues
fv = FeatureValues.AudioGuestBook;
content = ContentWrapper.GetContent(id);
lvItems.DataSource = content;
lvItems.DataBind();
}
And all was fine, and it rendered nicely. Except when you clicked to change a page, that is.
From there, weirdness ensued; it was out of sync, always one step behind. If you clicked page 2, nothing happened. If you then clicked page 3, it went to page 2. If you went back to 1, it went to 3… and so on. This led to a wild chase through several hours and pots of coffee using Google, which finally led me to a forum post. And there the answer was! It suddenly became clear: a solution which was, in the end, rather simple, if a little obscure. I added:
onpagepropertieschanging=”lvItems_PagePropertiesChanging”
to the ListView in the .ascx file, and
protected void lvItems_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs
e)
{
this.dpDataPager.SetPageProperties(e.StartRowIndex,
e.MaximumRows, false);
bind();
}
in the codebehind. This caused a change in the page to update both the listview and the data shown – something that I had been trying to find in a handler for the paging control, rather than the listview.
So there you have it: How to get a paged listview by using a data source set in the codebehind.













