Search code examples
c#asp.netpaginationviewstate

Paging in repeater: viewstate returns always null


I'm trying to implement paging in a repeater using PagedDataSource. The problem is that when I click on the "next" button the page is still the same, it doesn't load the other items. I figured out that viewstate returns always null, I don't know if this can be the problem.

This is the c# code:

public partial class Users 
{
    private int _pageSize;
    PagedDataSource page = new PagedDataSource();

    private const bool blnAllowPaging = true;
    private const int iPageSize = 3;


    protected void Page_Load(object sender, EventArgs e)
    {
        // if page is loaded for the first time call BindRepeater()
        if (!Page.IsPostBack)
        {
            // Load the table
            BindRepeater();
        }
    }


    protected void lnkFirst_Click(object sender, EventArgs e)
    {
        // Set viewstate variable to the first page
        CurrentPage = 0;
        BindRepeater();
    }

    protected void lnkPrevious_Click(object sender, EventArgs e)
    {
        // Set viewstate variable to the previous page
        CurrentPage -= 1;
        BindRepeater();
    }
    protected void lnkNext_Click(object sender, EventArgs e)
    {
        // Set viewstate variable to the next page
        CurrentPage += 1;
        BindRepeater();
    }

    protected void lnkLast_Click(object sender, EventArgs e)
    {
        // Set viewstate variable to the last page
        CurrentPage = page.PageCount - 1;
        BindRepeater();
    }
    private void FillPagesDropDownList(int iTotalPages)
    {
        ddlpageNumbers.Items.Clear();
        for (int i = 1; i <= iTotalPages; i++)
        {
            ddlpageNumbers.Items.Add(new ListItem(i.ToString(), i.ToString()));
        }
    }

    protected void ddlpageNumbers_SelectedIndexChanged(object sender, EventArgs e)
    {
        CurrentPage = ddlpageNumbers.SelectedIndex;
        BindRepeater();
    }

    private int CurrentPage
    {
        get
        {
            EnableViewState = true;
            object obj = ViewState["CurrentPage"];
            return (obj == null) ? 0 : (int)obj;
        }
        set
        {
            this.ViewState["CurrentPage"] = value;
        }
    }

    private void BindRepeater()
    {
        page.AllowPaging = blnAllowPaging;
        page.PageSize = iPageSize;

        lblTotalPages.Text = page.PageCount.ToString();
        FillPagesDropDownList(page.PageCount);

        // Disable buttons if necessary
        lnkFirst.Enabled = !page.IsFirstPage;
        lnkPrevious.Enabled = !page.IsFirstPage;
        lnkNext.Enabled = !page.IsLastPage;
        lnkLast.Enabled = !page.IsLastPage;
        // Set the PagedDataSource's current page
        page.CurrentPageIndex = CurrentPage;
        ddlpageNumbers.SelectedIndex = page.CurrentPageIndex;

        List<USERS> users = GetUsers(); // list of users taken from db
        page.DataSource = users;
        page.DataBind();

    }
}

This is the asp.net code:

<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<style type="text/css">
    .style1
    {
        width: 528px;
    }
</style>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:Repeater ID="m_SupportersRepeater" runat="server"  OnItemDataBound="SupportersRepeater_OnItemDataBound">
<HeaderTemplate>
    <table border="1" width="90%">
        <tr>
            <td>Name</td>
            <td>Family Name</td>
            <td>Age</td>
            <td>City</td>
        </tr>
</HeaderTemplate>

<ItemTemplate>
    <tr>
        <td><%# DataBinder.Eval(Container.DataItem, "FIRSTNAME")%></td>
        <td><%# DataBinder.Eval(Container.DataItem, "LASTNAME")%></td>
        <td><%# DataBinder.Eval(Container.DataItem, "AGE")%></td>
        <td><%# DataBinder.Eval(Container.DataItem, "CITY")%></td>
    </tr>
</ItemTemplate>

<FooterTemplate>
    </table>
</FooterTemplate>
</asp:Repeater>
<br />
<table style="margin-left: 214px">
 <tr align="center">
    <td colspan="4" class="style1">
        <asp:LinkButton ID="lnkFirst" runat="server" ForeColor="Black" Text="First" onclick="lnkFirst_Click" ></asp:LinkButton>&nbsp;
        <asp:LinkButton ID="lnkPrevious" runat="server" ForeColor="Black"  Text="Previous" OnClick="lnkPrevious_Click" >     </asp:LinkButton>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        Page&nbsp;
        <asp:DropDownList ID="ddlpageNumbers" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlpageNumbers_SelectedIndexChanged">    </asp:DropDownList>&nbsp;of&nbsp;
        <asp:Label ID="lblTotalPages" runat="server">    </asp:Label>&nbsp;Pages.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <asp:LinkButton ID="lnkNext" runat="server" ForeColor="Black" Text="Next" Onclick="lnkNext_Click" ></asp:LinkButton>&nbsp;
        <asp:LinkButton ID="lnkLast" runat="server" ForeColor="Black" Text="Last" Onclick="lnkLast_Click" ></asp:LinkButton>
    </td>
</tr>
</table>
</asp:Content>

Solution

  • In your BindRepeater method, try moving the last three lines of code (where you retrieve data and bind it to your PagedDataSource member) to the top of the method so that your PagedDataSource object is populated before you start evaluating its properties. I think loading data at the end of the method resets the page.CurrentPageIndex property to zero. So load the PagedDataSource first, set paging properties on the PagedDataSource, THEN set your Repeater's DataSource property to the PagedDataSourceObject.