Click here to Skip to main content
Email Password   helpLost your password?

Introduction

This is a WebControl that provides an easy way to prepare an ASP.NET GridView to be paged and printed in the browser.

How It Works

This control inherits from the regular GridView, so no original feature will be lost.
We implement the paging by overriding the method that renders the gridview row when we detect that it should be the last row in the current page. This is done by using the method SetRenderMethodDelegate of the row.

void ReportGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow)
    {
        _currentPageRow++;
        if (_currentPageRow == this._printPageSize)
        {
            _currentPageRow = 0;
            e.Row.SetRenderMethodDelegate(PageBreakRender);
        }
    }
}

Now, the last row of each page will use our PageBreakRender method to render itself. So, in the PageBreakRender method we have to manually render the contents of the row, that's where we are going to close the table, insert a page break and open the table again in the next page.
Here's the PageBreakRender method:

protected void PageBreakRender(HtmlTextWriter output, Control container)
{
    HtmlTextWriter cellsWriter = new HtmlTextWriter(new StringWriter());
    foreach (Control c in container.Controls)
    {
        TableCell cell = (TableCell)c;
        cell.RenderControl(cellsWriter);
    }

    output.Write("<tr>");
    output.Write(cellsWriter.InnerWriter.ToString());
    output.Write("</tr></table>");
    output.Write(GetPageFooterHtml());

    //If it is the last row, don't show the next header

    if (_currentPrintPage ==  PrintPageCount && Rows.Count % 
        (_currentPrintPage) == 0)
        return;

    output.Write("<div style=\"page-break-after:always;\"></div>");
    output.Write(GetHeaderHtml());
    _currentPrintPage++;
}

Note that there is a call to a method named GetHeaderHtml. This method returns the header of the GridView, so it can be rendered again in the new page.

This is the main idea behind the control. I also added the capability to render a custom page header and page footer defined in templates. Enabling the use of templates is very straight forward and you should find plenty of resources about it on the internet. You can also take a closer look at the source code to see how it works.

How To Use It

This control will work just like a regular GridView, but to enable paging we should look at a couple of properties:

The control's opening tag should be something like this:

<wc:ReportGridView runat="server" BorderWidth="1" 
    ID="gvSample" PrintPageSize="23" AllowPrintPaging="true" 
    AutoGenerateColumns="false">

That's it. Adding these two properties will make ASP.NET output several GridViews, one for each page.

You can still insert custom content between each GridView, before and after the page break. This can be accomplished by defining a PageHeaderTemplate and a PageFooterTemplate.

Here is the GridView used in our sample page:

<wc:ReportGridView runat="server" BorderWidth="1" 
    ID="gvSample" AutoGenerateColumns="false" PrintPageSize="23" 
    AllowPrintPaging="true"
            Width="600px">
        <Columns>
            <asp:BoundField DataField="Name" HeaderText="Customer Name" />
            <asp:BoundField DataField="PhoneNumber" 
                HeaderText="Customer Phone" 
                ItemStyle-HorizontalAlign="center" />
        </Columns>
        <PageHeaderTemplate>
            <br />
            PAGE HEADER TEMPLATE HERE
            <br />
        </PageHeaderTemplate>
        <PageFooterTemplate>
            <br />

            <hr />
            Page <%# gvSample.CurrentPrintPage.ToString() %> / 
                    <%# gvSample.PrintPageCount %>

        </PageFooterTemplate>
    </wc:ReportGridView>

Notice that there are a couple more properties that we can use in the templates:

It can be used to display the page number at the footer or at the header of the page, as we can see in the sample picture above.

Known Issues

When using Firefox, the BorderWith property must be set explicitly. Otherwise the border of the GridView won't be displayed.

Conclusion

In this article, we saw how we can extend the GridView control to add custom rendering logic and provide a useful feature such as preparing it for printing in the browser.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Generalprinting a gridview with paging
annamthana
20:19 24 Jul '09  
hi experts

anybody help me please

how can i place the datalist in the page heder template,i want to bind the data in codebehind


please help us...........

thanks in advance.....


Confused
GeneralHow about when there are odd number of records in the gridview?
shravaniraj
4:50 9 Jul '09  
Hi

Thanks for the article it helped me lot.
I have moderated it according to my req. as i want to get the preview of the gridview in a new page when i hit the print button.And my gridview has odd number of records..suppose 37 records and printpagesize is 20..i am getting inproper pagination in the preview..like for the first page i am getting only 3 records, in the next page 20 records and getting one more extra page with the rest of the records with pagefooter 3/2 ...


any help is greatly appreciated..as i tried so many ways from past 3days and could not find the solution...

hope a prompt reply..

thanks in advance
QuestionPrinting a GridView with Paging
annamthana
22:51 28 Jun '09  
Hi Cassio Mosqueira

Thanks for this great article its very much used for me.

my question is how can i place the datalist in the Page Header Template

I try some way, but i dont get any solution can you guid me..?


regards

Thanasekaran.P
Generalimports shared.webcontrols is not valid as indentifier
Member 3895252
14:49 13 Apr '09  
Well, I'm stumped.


I can compile and run a slightly modified version of your custom control in C# but when I try to use the control in a vb.net application, vs 2005 has a absolute fit with it.

Am I missing something here? I copied the shared.webcontrols.dll to the /bin folder for the vb application then registered the dll. In vb I enter a imports shared.webcontrols
and on the web page code I include a register line

I was using the standard asp:gridview and changed that to the we:reportsgridview ....
and at this point vs 2005 starts complaining when I try to compile and run in debug mode.


any ideas?
GeneralHeaderstyle - alignment
katem6
2:10 31 Jul '08  
Thank you very much for that extremely useful control.

I have only one question:
How can I change the alignment in the header from middle to left?

Thank you very much in advance,
Ciao Kate

GeneralRe: Headerstyle - alignment
Cassio Mosqueira
4:10 31 Jul '08  
Have you tried putting the header content inside a div aligned to the left?

<div style="text-align:left">
 Header here
</div>


Regards,
Cassio Alves
Cool

GeneralOne small fix
ingridt
12:44 19 Nov '07  
Thank you thank you thank you! This is exactly what I needed.

One small comment... I noticed the code was inserting an extra "<tr>" before the last row on each page which was affecting the formatting. I was able to fix that by removing the line

output.Write("<tr>");

in PageBreakRender in ReportGridView.cs.

Ingrid</tr></tr>
modified on Friday, December 21, 2007 9:57:56 AM


Last Updated 18 Oct 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010