20

From everything I've read, it seemed that adding paging to a ListView control should be dead simple, but it's not working for me. After adding the ListView and DataPager controls to the form and wiring them together, I'm getting very odd behavior. The DataPager correctly limits the ListView's page size, but clicking the paging buttons doesn't affect the ListView at all. The paging buttons seem to think they are doing they're job, as the last button is disabled when you go to the last page, etc., but the ListView never changes. Also, it takes two clicks on the DataPager to get it to do anything, i.e., clicking on Last once does nothing, but clicking it a second time causes the DataPager to react as if the last page is now selected.

The only thing I can think of is that I'm binding the DataSource at runtime (to a LINQ object), not using a LinqDataSource control or anything. Has anyone seen this behavior? Am I doing something wrong? Here's the code I'm using:

<asp:DataPager ID="HistoryDataPager" runat="server" PagedControlID="HistoryListView" PageSize="10">
    <Fields>
        <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="true" ShowLastPageButton="true" />
    </Fields>
</asp:DataPager>

<asp:ListView ID="HistoryListView" runat="server">
    ...
</asp:ListView>

In the code-behind:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        HistoryListView.DataSource = From x in myContext.myTables ...
        DataBind()
    End If

End Sub
gfrizzle
  • 12,419
  • 19
  • 78
  • 104

7 Answers7

30

We need to databind list view again in OnPreRender event.

protected override void OnPreRender(EventArgs e)
        {
            ListView1.DataBind();
            base.OnPreRender(e);
        }

--Update

After working on a few list views with asp.net ajax, I saw a solution that makes more sense than the above one. You would normally data bind Listview on page load method or a button click event handler and when there is post back the data binding would be lost as described above in the problem. So, we need to data bind again on page properties changed event handler for the list view.

ListView_PagePropertiesChanged(object sender, EventArgs e)
{
ListView.DataSource=someDatasource;
ListView.DataBind()
}
Even Mien
  • 44,393
  • 43
  • 115
  • 119
Syam
  • 1,629
  • 1
  • 20
  • 32
  • 1
    You don't need to DataBind it *again*. But yes, you can fix this problem by databinding in the prerender. – Neil Feb 20 '09 at 20:29
  • 1
    This is the most stupid thing I've ever seen from ASP.net (though I'm sure there is worse). But thank you for finding it. I never thought there would be a pre_render bug. – Dexter Mar 28 '12 at 18:02
  • @Syam when i use the pre render override the listView datasource comes out to be null(on clicking next button) and then no record is displayed... any guesses ? – tariq Mar 05 '13 at 09:36
  • @tariq the datasource will be null unless you assign some data to it before prerender. Or you can assign the data again before calling DataBind method. But a better way to handle this is to use PagePropertiesChanged event as described above. – Syam Mar 05 '13 at 21:38
4

One More Solution, Its Simple, Just Get "ID" in "QUERY-STRING" from the Database, Now Set it to the Pager Control Property as [ QueryStringField="ID" ] like:

<asp:DataPager ID="DataPagerProducts" runat="server" QueryStringField="ID" PageSize="3">
                            <Fields>
                                <asp:NextPreviousPagerField ShowFirstPageButton="True" ShowNextPageButton="False" />
                                <asp:NumericPagerField />
                                <asp:NextPreviousPagerField ShowLastPageButton="True" ShowPreviousPageButton="False" />
                            </Fields>
                        </asp:DataPager>

Note: if not woking, then set also [ PagedControlID="ListView_Name" ].

ASR
  • 1,801
  • 5
  • 25
  • 33
Mustafa Iqbal
  • 73
  • 1
  • 4
1

Also, if the data source of your ListView is changed (e.g. if displaying data based on search parameters), don't forget to reset the pager every time the data source is updated. With a ListView this is not as straightforward as some other data-bound controls (e.g. GridView):

private void ResetListViewPager()
{
    DataPager pager = (DataPager)ListViewMembers.FindControl("DataPager1");
    if (pager != null)
    {
        CommandEventArgs commandEventArgs = new CommandEventArgs(DataControlCommands.FirstPageCommandArgument, "");
        // MAKE SURE THE INDEX IN THE NEXT LINE CORRESPONDS TO THE CORRECT FIELD IN YOUR PAGER
        NextPreviousPagerField nextPreviousPagerField = pager.Fields[0] as NextPreviousPagerField;
        if (nextPreviousPagerField != null)
        {
            nextPreviousPagerField.HandleEvent(commandEventArgs);
        }

        // THIS COMMENTED-OUT SECTION IS HOW IT WOULD BE DONE IF USING A NUMERIC PAGER RATHER THAN A NEXT/PREVIOUS PAGER
        //commandEventArgs = new CommandEventArgs("0", "");
        //NumericPagerField numericPagerField = pager.Fields[0] as NumericPagerField;
        //if (numericPagerField != null)
        //{
        //    numericPagerField.HandleEvent(commandEventArgs);
        //}
    }
}
1

Take a look at the ListViewPagedDataSource.

private ListViewPagedDataSource GetProductsAsPagedDataSource(DataView dv)
{
// Limit the results through a PagedDataSource
ListViewPagedDataSource pagedData = new ListViewPagedDataSource();
pagedData.DataSource = dv;
pagedData.MaximumRows = dv.Table.Rows.Count;
pagedData.TotalRowCount = dpTop.PageSize;

if (Request.QueryString[dpTop.QueryStringField] != null)
  pagedData.StartRowIndex = (Convert.ToInt32(Request.QueryString[dpTop.QueryStringField]) - 1) * dpTop.PageSize;
else
  pagedData.StartRowIndex = 0;

return pagedData;
}

Though, I have a problem viewing the last page. The DataPager jumps back to the first page, but the data displayed is the last page.

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
MartinHN
  • 19,542
  • 19
  • 89
  • 131
1

Bind the listview at datapager's pre render event not at page load. Please see the solution here

Community
  • 1
  • 1
arsamaga
  • 11
  • 1
0
<asp:ListView ID="ListView1" runat="server" DataSourceID="sdsImages">
    <ItemTemplate>
        <div class="photo sample12">
                <asp:Image ID="img_Galerie" runat="server" ImageUrl='<%# "~/imageHandler.ashx?ID=" + Eval("ImageID") %>' />
        </div>
    </ItemTemplate>
</asp:ListView>
<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" PageSize="3" QueryStringField="ImageID">
    <Fields>
        <asp:NextPreviousPagerField ShowFirstPageButton="True" ShowNextPageButton="False" />
        <asp:NumericPagerField />
        <asp:NextPreviousPagerField ShowLastPageButton="True" ShowPreviousPageButton="False" />
    </Fields>
</asp:DataPager>
<asp:SqlDataSource ID="sdsImages" runat="server"
    ConnectionString="<%$ ConnectionStrings:DBCS %>"
    SelectCommand="SELECT ImageID FROM  Images ">

0

try this:

protected void ListView1_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
    DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
    ListView1.DataSource = productList;
    ListView1.DataBind();
    DataPager1.DataBind();
}
Masoumeh Karvar
  • 791
  • 1
  • 14
  • 32