Issues with custom DataPager

2019-06-06 11:03发布

I am trying to extend the asp.net DataPager control into a custom control with predefined templates. This is the desired output

enter image description here

Problems:

  1. When I load the page containing the custom DataPager for the first time, the SelectMethod of my ObjectDataSource is called 3 times.
  2. When I try to load another page of data using the DataPager, the SelectMethod is called twice.
  3. When I try to load another page of data, either by using the Next/Previous buttons or the DropDownList, the page does not change. I ran some debugging and found that it was not passing the correct value to the StartRowIndexParameter of the SelectMethod (it just passed 0 everytime it called the method).

Here's the code for my custom control.

public class DataPagerDDL : DataPager
{
    protected override void RenderContents(HtmlTextWriter writer)
    {
        //add custom template
        TemplatePagerField templateField = new TemplatePagerField();
        templateField.PagerTemplate = new CustomTemplate();
        Fields.Add(templateField);

        //add previous/next page template
        NextPreviousPagerField nextPreviousField = new NextPreviousPagerField();            
        nextPreviousField.ShowFirstPageButton = false;
        nextPreviousField.ShowLastPageButton = false;
        nextPreviousField.PreviousPageText = "<<";
        nextPreviousField.NextPageText = ">>";
        Fields.Add(nextPreviousField);

        base.RenderContents(writer);
    }

    public void cmbPage_SelectedIndexChanged(object sender, EventArgs e)
    {
        DropDownList cmbPage = (DropDownList)sender;
        this.SetPageProperties(cmbPage.SelectedIndex * MaximumRows, MaximumRows, true);
    }
}

public class CustomTemplate : ITemplate
{
    /// <summary>
    /// Insert an instance of text and controls into the specified container.
    /// </summary>
    public void InstantiateIn(Control container)
    {
        DataPagerFieldItem caller = (DataPagerFieldItem)container;
        DataPagerDDL pager = (DataPagerDDL)caller.Parent;
        int totalPages = pager.TotalRowCount / pager.MaximumRows;
        if (pager.TotalRowCount % pager.MaximumRows > 0) totalPages += 1;
        int currentPage = (pager.StartRowIndex / pager.MaximumRows) + 1;

        DropDownList cmbPage = new DropDownList();
        cmbPage.ID = "cmbPage";
        cmbPage.AutoPostBack = true;
        cmbPage.SelectedIndexChanged += new EventHandler(pager.cmbPage_SelectedIndexChanged);
        for (int i = 1; i <= totalPages; i++)
        {
            ListItem item = new ListItem(i.ToString(), i.ToString());
            if (i == currentPage) item.Selected = true;
            cmbPage.Items.Add(item);
        }

        pager.Controls.Add(new LiteralControl("Page "));
        pager.Controls.Add(cmbPage);
        pager.Controls.Add(new LiteralControl(" of " + totalPages.ToString() + " pages | "));
    }
}

And this is what my page looks like:

<asp:ListView ID="ListView1" DataSourceID="ods1" ... >
...
</asp:ListView>

<custom:DataPagerDDL ID="CustomDataPager" runat="server" PagedControlID="ListView1" 
        PageSize="25">
</custom:DataPagerDDL>    

<asp:ObjectDataSource ID="ods1" ... >
</asp:ObjectDataSource>

What should I do to make my custom DataPager work as intended? Thanks in advance! :)

1条回答
▲ chillily
2楼-- · 2019-06-06 11:45

I suspect you're creating the pager fields too late in the page lifecycle. Try creating them from the Init event of the DataPagerDDL class.

Also, your CustomTemplate should be adding the controls to the container, not the pager.

public class DataPagerDDL : DataPager
{
    protected override void OnInit(EventArgs e)
    {
        CreateDefaultPagerFields();
        base.OnInit(e);
    }

    protected virtual void CreateDefaultPagerFields()
    {
        //add custom template
        TemplatePagerField templateField = new TemplatePagerField();
        templateField.PagerTemplate = new CustomTemplate();
        Fields.Add(templateField);

        //add previous/next page template
        NextPreviousPagerField nextPreviousField = new NextPreviousPagerField();            
        nextPreviousField.ShowFirstPageButton = false;
        nextPreviousField.ShowLastPageButton = false;
        nextPreviousField.PreviousPageText = "<<";
        nextPreviousField.NextPageText = ">>";
        Fields.Add(nextPreviousField);
    }

    public void cmbPage_SelectedIndexChanged(object sender, EventArgs e)
    {
        DropDownList cmbPage = (DropDownList)sender;
        SetPageProperties(cmbPage.SelectedIndex * MaximumRows, MaximumRows, true);
    }
}

public class CustomTemplate : ITemplate
{
    public void InstantiateIn(Control container)
    {
        DataPagerFieldItem caller = (DataPagerFieldItem)container;
        DataPagerDDL pager = (DataPagerDDL)caller.Parent;
        int totalPages = pager.TotalRowCount / pager.MaximumRows;
        if (pager.TotalRowCount % pager.MaximumRows > 0) totalPages += 1;
        int currentPage = (pager.StartRowIndex / pager.MaximumRows) + 1;

        DropDownList cmbPage = new DropDownList();
        cmbPage.ID = "cmbPage";
        cmbPage.AutoPostBack = true;
        cmbPage.SelectedIndexChanged += pager.cmbPage_SelectedIndexChanged;

        for (int i = 1; i <= totalPages; i++)
        {
            ListItem item = new ListItem(i.ToString(), i.ToString());
            if (i == currentPage) item.Selected = true;
            cmbPage.Items.Add(item);
        }

        container.Controls.Add(new LiteralControl("Page "));
        container.Controls.Add(cmbPage);
        container.Controls.Add(new LiteralControl(" of " + totalPages + " pages | "));
    }
}
查看更多
登录 后发表回答