Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

GridView with DataPager in ASP.NET 4.0

4.57/5 (8 votes)
12 Feb 2014CPOL3 min read 45.9K  
GridView with DataPager in ASP.NET 4.0

Introduction

To page through data in a control that implements the IPageableItemContainer interface, DataPager control can be used. GridView has its own paging and does not implement IPageableItemContainer interface. ListView is the only control that works with DataPager.

Background

The DataPager control supports built-in paging user interface (UI). NumericPagerField object enables users to select a page of data by page number. NextPreviousPagerField object enables users to move through pages of data one page at a time, or to jump to the first or last page of data. The size of the pages of data is set by using the PageSize property of the DataPager control. One or more pager field objects can be used in a single DataPager control. Custom paging UI can be created by using the TemplatePagerField object. In the TemplatePagerField template, the DataPager control is referenced by using the Container property which provides access to the properties of the DataPager control. These properties include the starting row index, the page size, and the total number of rows currently bound to the control.

Using the Code

So let's begin extending the GridView with the IPageableItemContainer interface.

Define a new class as below:

C#
public class DataPagerGridView : GridView, IPageableItemContainer
{  
      public DataPagerGridView() : base() 
        {  
            PagerSettings.Visible = false;
        } 
}  

private static readonly object EventTotalRowCountAvailable = new object();

MaximumRows will be equal to the PageSize property:

C#
public int MaximumRows
        {
            get { return this.PageSize; }
        }  

StartRowIndex can be calculated from the PageSize and PageIndex properties:

C#
public int StartRowIndex
        {
            get { return this.PageSize * this.PageIndex; }
        }

The SetPageProperties method is called by the DataPager control every time the control must update the page-related properties. When implemented by a class, the SetPageProperties method must internally update the MaximumRows and StartRowIndex properties by using the values of the maximumRows and startRowIndex parameters. So set the Grid with appropriate parameters and bind to right chunk of data.

C#
public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
        {
            int newPageIndex = (startRowIndex / maximumRows);
            this.PageSize = maximumRows;
            if (this.PageIndex != newPageIndex)
            {
                bool isCanceled = false;
                if (databind)
                {
                    //  create the event arguments and raise the event
                    GridViewPageEventArgs args = new GridViewPageEventArgs(newPageIndex);
                    this.OnPageIndexChanging(args);
                    isCanceled = args.Cancel;
                    newPageIndex = args.NewPageIndex;
                }
                //  if the event wasn't cancelled change the paging values
                if (!isCanceled)
                {
                    this.PageIndex = newPageIndex;
                    if (databind)
                        this.OnPageIndexChanged(EventArgs.Empty);
                }
                if (databind)
                    this.RequiresDataBinding = true;
            }
        } 

For the DataPager to render the correct number of page buttons and enable/disable them, it needs to know the total number of rows and the Page Size. But this information is with the GridView and not known to the DataPager. As the GridView control inherits from CompositeDataboundControl which contains a variant of the CreateChildControls method, that also takes in a property indicating whether the control is being bound to data or simply re-rendered. The GridView uses this method to bind to its data source and here we can place a trigger for the TotalRowCountAvailable event to be raised. Call base control's CreateChildControls method and determine the number of rows in the source, then fire off the event with the derived data and then we return the original result.

C#
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
        {
            int rows = base.CreateChildControls(dataSource, dataBinding);

            //  if the paging feature is enabled, determine the total number of rows in the datasource
            if (this.AllowPaging)
            {
                // if we are databinding, use the number of rows that were created, 
                // otherwise cast the datasource to an Collection and use that as the count
                int totalRowCount = dataBinding ? rows : ((ICollection)dataSource).Count;

                //  raise the row count available event
                IPageableItemContainer pageableItemContainer = this as IPageableItemContainer;
                this.OnTotalRowCountAvailable(new PageEventArgs
                (pageableItemContainer.StartRowIndex, pageableItemContainer.MaximumRows, totalRowCount));

                //  make sure the top and bottom pager rows are not visible
                if (this.TopPagerRow != null)
                    this.TopPagerRow.Visible = false;

                if (this.BottomPagerRow != null)
                    this.BottomPagerRow.Visible = false;
            }
            return rows;
        }  

        public event EventHandler<PageEventArgs> TotalRowCountAvailable
        {
            add { base.Events.AddHandler(PagingGridView.EventTotalRowCountAvailable, value); }
            remove { base.Events.RemoveHandler(PagingGridView.EventTotalRowCountAvailable, value); }
        }

        protected virtual void OnTotalRowCountAvailable(PageEventArgs e)
        {
            EventHandler<PageEventArgs> handler = 
            (EventHandler<PageEventArgs>)base.Events[PagingGridView.EventTotalRowCountAvailable];
            if (handler != null)
            {
                handler(this, e);
            }
        }

That's all you are done, put the control on aspx page and use DataPager with GridView Control.

HTML
<cc1:PagingGridView ID="pgvGrid" AllowPaging="True" 
OnPageIndexChanging="pgvGrid_PageIndexChanging" runat="server">                     
                    </cc1:PagingGridView>
                    <asp:DataPager ID="pgGrid" runat="server" 
                    PageSize="10" PagedControlID="pgvGrid">
                        <Fields>
                            <asp:NextPreviousPagerField ButtonCssClass="command" 
                            FirstPageText="«" PreviousPageText="‹"
                                RenderDisabledButtonsAsLabels="true" 
                                ShowFirstPageButton="true" ShowPreviousPageButton="true"
                                ShowLastPageButton="false" ShowNextPageButton="false" />
                            <asp:NumericPagerField ButtonCount="7" 
                            NumericButtonCssClass="command" CurrentPageLabelCssClass="current"
                                NextPreviousButtonCssClass="command" />
                            <asp:NextPreviousPagerField ButtonCssClass="command" 
                            LastPageText="»" NextPageText="›"
                                RenderDisabledButtonsAsLabels="true" 
                                ShowFirstPageButton="false" ShowPreviousPageButton="false"
                                ShowLastPageButton="true" ShowNextPageButton="true" />
                        </Fields>
                    </asp:DataPager>
C#
protected void pgvGrid_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            pgvGrid.PageIndex = e.NewPageIndex;

            LoadGrid();
        }  
HTML
<input type="submit" name="Button1" 
value="Generate" id="Button1" />  
Column1 Column2 Column3 Column4 Column5 Column6 Column7 Column8 Column9 Column10 Column11 Column12
R1C1 R1C2 R1C3 R1C4 R1C5 R1C6 R1C7 R1C8 R1C9 R1C10 R1C11 R1C12
R2C1 R2C2 R2C3 R2C4 R2C5 R2C6 R2C7 R2C8 R2C9 R2C10 R2C11 R2C12
R3C1 R3C2 R3C3 R3C4 R3C5 R3C6 R3C7 R3C8 R3C9 R3C10 R3C11 R3C12
R4C1 R4C2 R4C3 R4C4 R4C5 R4C6 R4C7 R4C8 R4C9 R4C10 R4C11 R4C12
R5C1 R5C2 R5C3 R5C4 R5C5 R5C6 R5C7 R5C8 R5C9 R5C10 R5C11 R5C12
R6C1 R6C2 R6C3 R6C4 R6C5 R6C6 R6C7 R6C8 R6C9 R6C10 R6C11 R6C12
R7C1 R7C2 R7C3 R7C4 R7C5 R7C6 R7C7 R7C8 R7C9 R7C10 R7C11 R7C12
R8C1 R8C2 R8C3 R8C4 R8C5 R8C6 R8C7 R8C8 R8C9 R8C10 R8C11 R8C12
R9C1 R9C2 R9C3 R9C4 R9C5 R9C6 R9C7 R9C8 R9C9 R9C10 R9C11 R9C12
R10C1R10C2R10C3R10C4R10C5R10C6R10C7R10C8R10C9R10C10R10C11 R10C12

« ‹ 1 2 3 4 5 6 7 ... › »

HTML
<input type="submit" name="Button2" value="Save" id="Button2" />  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)