1

I'm currently using IPagedList to efficiently page my data.

When using with a GridView I can set the page index in the GridView.PageIndexChanging event and rebind the grid.

The problem is, the GridView.PageCount property is readonly so the default pager only displays 1 page.

I suppose I'm going to have to roll my own GridView implementation to get round this? Has anyone got one that they have already done?

Ben Foster
  • 34,340
  • 40
  • 176
  • 285

2 Answers2

6

Helped by this post I created my own custom GridView control that allowed me to override the initialization of the pager and set the record count.

public class CustomGridView : GridView
{
    private const string _virtualItemCount = "virtualItemCount";
    private const string _currentPageIndex = "currentPageIndex";

    [Browsable(true), Category("Custom")]
    [Description("Set the virtual item count for this grid")]
    public int VirtualItemCount {
        get
        {
            if (ViewState[_virtualItemCount] == null)
                ViewState[_virtualItemCount] = -1;
            return Convert.ToInt32(ViewState[_virtualItemCount]);
        }
        set
        {
            ViewState[_virtualItemCount] = value;
        }
    }

    private int CurrentPageIndex
    {
        get
        {
            if (ViewState[_currentPageIndex] == null)
                ViewState[_currentPageIndex] = 0;
            return Convert.ToInt32(ViewState[_currentPageIndex]);
        }
        set
        {
            ViewState[_currentPageIndex] = value;
        }
    }

    public override object DataSource
    {
        get
        {
            return base.DataSource;
        }
        set
        {
            base.DataSource = value;
            this.CurrentPageIndex = this.PageIndex;
        }
    }

    protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)
    {
        if (CustomPaging)
        {
            pagedDataSource.VirtualCount = this.VirtualItemCount;
            pagedDataSource.CurrentPageIndex = this.CurrentPageIndex;
        }
        base.InitializePager(row, columnSpan, pagedDataSource);
    }

    public bool CustomPaging {
        get { return (this.VirtualItemCount != -1); }
    }
}

Then on the CustomGridView.PageIndexChanging event we set the page index and reload our data (passing the page index and page size to our repository method):

    protected void gvAccounts_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        gvAccounts.PageIndex = e.NewPageIndex;
        BindGrid(e.NewPageIndex, gvAccounts.PageSize);
    }


    protected void BindGrid(int pageIndex, int pageSize)
    {
        var accounts = AccountManager.GetAllAccounts<int>(pageIndex, pageSize, x=> x.AccountId);
        gvAccounts.VirtualItemCount = accounts.TotalCount;
        gvAccounts.DataSource = accounts;
        gvAccounts.DataBind();
    }

Hope this helps.

Community
  • 1
  • 1
Ben Foster
  • 34,340
  • 40
  • 176
  • 285
  • Hi, I know this is posted awhile ago. I tired this, and in most cases it works. However, When I am on the second page (with page size 20), When page is being loaded InitializePage will be called and I notcied PagedDataSource.DataSource is a dummydatasource. and this is what causing me a problem. later on, after page_load event, I tried doing GridView.rows.count, it is showing me that I have items in the list, while I only have 18 on the second page. and I check inside that list, those 18 pages are correct, but there are 2 extra items that are empty. Any clue? – Dhana Jun 24 '13 at 15:30
1

This is what I used to accomplish paging and sorting with the gridview when binding to IQueryable: http://bradoyler.com/post/399042473/using-the-asp-net-gridview-with-objectdatasource-and

Hope that helps also!

brad oyler
  • 3,669
  • 1
  • 20
  • 22