Repeating page headers in the Document Object

WinForms

ComponentOne's WinForms controls

Repeating page headers in the Document Object

  • rated by 0 users
  • This post has 4 Replies |
  • 2 Followers
  • Hi

    I am using the PrintDocument object to generate the report and the report has 4 pages.

    The first page has 3 headers( namely 1,2,3) and in the remaining pages, I would like to display only 1, 3 headers. How do I do that? Do you have any samples?

    I am trying to use the "PageAdded" in the Document object to add the headers and getting the "Collection was modified; enumeration operation may not execute" message.

    I have also created a sample Windows application to replicate this behaviour. I have added the "C1PrintDocument" and "C1PrintPreviewControl" controls in the form. Here is the form code. 

    Imports C1.C1Preview

    Public Class Form2

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Me.Close()

    End Sub

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    GeneratePages()

    End Sub

    Private Sub GeneratePages()Dim intK As Int16 = 0

    AddHeader1()

    AddHeader2()

    AddHeader3()

    Dim objTable As New RenderTable()

    For intK = 1 To 200

    objTable.Cells(intK, 0).Text = "Line " & intK

    Next

    C1PrintDocument1.Body.Children.Add(objTable)

    objTable = Nothing

    C1PrintDocument1.Reflow()

    End Sub

    Private Sub AddHeader1()

    Dim objTable As New RenderTable()

    objTable.Cells(0, 0).Text = "header 1"

    objTable.Style.BackColor = Color.LightGray

    C1PrintDocument1.Body.Children.Add(objTable)

    objTable = Nothing

    End Sub

    Private Sub AddHeader2()

    Dim objTable As New RenderTable()

    objTable.Cells(0, 0).Text = "header 2"

    objTable.Style.BackColor = Color.LightCoral

    C1PrintDocument1.Body.Children.Add(objTable)

    objTable = Nothing

    End Sub

    Private Sub AddHeader3()

    Dim objTable As New RenderTable()

    objTable.Cells(0, 0).Text = "header 3"

    objTable.Style.BackColor = Color.LightYellow

    C1PrintDocument1.Body.Children.Add(objTable)

    objTable = Nothing

    End Sub

    Private Sub C1PrintDocument1_PageAdded(ByVal sender As C1.C1Preview.C1PrintDocument, ByVal e As C1.C1Preview.PageEventArgs) Handles C1PrintDocument1.PageAdded

    'If e.Page.PageNo > 1 Then

    ' AddHeader1()

    ' AddHeader3()

    'End If

    End Sub

    End Class

     

    In this report, how can I add the header1 and header3 in pages 2, 3 and 4. Any help would be appreciated.

     

    Regards, Karthik

  • You are not approaching this correctly. C1PrintDocument has built-in mechanism for page headers and footers, and that is what should be used in this case.

    Here's the modified version of your GeneratePages that does what you need, hope it helps:

     

        Private Sub GeneratePages()
            Dim intK As Int16 = 0

            Dim headerFirstPage As New RenderTable
            headerFirstPage.Cells(0, 0).Text = "header 1"
            headerFirstPage.Cells(0, 0).Style.BackColor = Color.LightGray
            headerFirstPage.Cells(1, 0).Text = "header 2"
            headerFirstPage.Cells(1, 0).Style.BackColor = Color.LightCoral
            headerFirstPage.Cells(2, 0).Text = "header 3"
            headerFirstPage.Cells(2, 0).Style.BackColor = Color.LightYellow

            Dim headerDefault As RenderTable = headerFirstPage.Clone
            headerDefault.Rows.Delete(1)

            C1PrintDocument1.PageLayouts.FirstPage = New PageLayout
            C1PrintDocument1.PageLayouts.FirstPage.PageHeader = headerFirstPage

            C1PrintDocument1.PageLayouts.Default = New PageLayout
            C1PrintDocument1.PageLayouts.Default.PageHeader = headerDefault

            Dim objTable As New RenderTable()

            For intK = 1 To 200
                objTable.Cells(intK, 0).Text = "Line " & intK
            Next

            C1PrintDocument1.Body.Children.Add(objTable)

            objTable = Nothing

            C1PrintDocument1.Reflow()
        End Sub
     

    Cheers, Dima.
  • Dima,

    Thanks for the quick response. I have one more question regarding the page headers.

    Based on the sample code, I can set the page headers only for first page, last page, odd or even pages. Is there a way, I can manually set the page headers for every page.

    For example, the "Employees" report includes the following sub reports.

     1. List of all employees (summary page)

    After printing the summary page, we need to print the sub reports by employee. The sub-reports include the following

    2. Project history for the employee (list of projects worked by the employee)

    3. Technical expertise for the employee

    4. Educational qualification and training

    The sub reports 2,3,4 prints for each employee in a separte pages and the sub report may exceed more than one page. The subreports include different headers also require sub report header in every page.

    How do we accomplish this format?. Any idea or direction would be greatly appreciated.

     Regards, Karthik

  • You can use the RenderObject's LayoutChangeBefore and LayoutChangeAfter properties to change page layout before or after any object in your document. Those properties are of the abstract type LayoutChangeBase, which has several derived types determining whether a new page or column is started when that layout change is applied (such as LayoutChangeNewPage, which inserts a page break). If you implement your sub-report as a separate render object, e.g. as a RenderTable, you can assign a LayoutChangeNewPage to its LayoutChangeBefore property, set Nested on that layout change to True so that the previous layout is restored when the sub-report returns, and specify any layout properties for the sub-report - including of course page headers/footers. Below is a small example:

        Private Sub GeneratePages()

            Dim intK As Int16 = 0

            Dim headerFirstPage As New RenderTable
            headerFirstPage.Cells(0, 0).Text = "header 1"
            headerFirstPage.Cells(0, 0).Style.BackColor = Color.LightGray
            headerFirstPage.Cells(1, 0).Text = "header 2"
            headerFirstPage.Cells(1, 0).Style.BackColor = Color.LightCoral
            headerFirstPage.Cells(2, 0).Text = "header 3"
            headerFirstPage.Cells(2, 0).Style.BackColor = Color.LightYellow

            Dim headerDefault As RenderTable = headerFirstPage.Clone
            headerDefault.Rows.Delete(1)

            C1PrintDocument1.PageLayouts.FirstPage = New PageLayout
            C1PrintDocument1.PageLayouts.FirstPage.PageHeader = headerFirstPage

            C1PrintDocument1.PageLayouts.Default = New PageLayout
            C1PrintDocument1.PageLayouts.Default.PageHeader = headerDefault

            Dim objTable As New RenderTable()

            For intK = 1 To 200
                objTable.Cells(intK, 0).Text = "Line " & intK
            Next

            C1PrintDocument1.Body.Children.Add(objTable)

            Dim t2 As New RenderTable
            For intK = 0 To 100
                t2.Cells(intK, 0).Text = String.Format("Table 2 row {0}", intK)
            Next
            Dim lcnp As New LayoutChangeNewPage
            t2.LayoutChangeBefore = lcnp
            lcnp.Nested = True
            lcnp.PageLayout = New PageLayout
            lcnp.PageLayout.PageHeader = New RenderText("NESTED PAGE HEADER")
            lcnp.PageLayout.PageFooter = New RenderText("NESTED PAGE FOOTER")
            C1PrintDocument1.Body.Children.Add(t2)

            C1PrintDocument1.Body.Children.Add(New RenderText("Last Render object"))

            C1PrintDocument1.Reflow()
        End Sub
     

    As an alternative, you can set AllowNonReflowableDocs to True on your C1PrintDocument, and then use its PageConfigure event to specify page layout for each page in code, e.g.:

      C1PrintDocument1.AllowNonReflowableDocs = True ' Needed to use PageConfigure event

    ...

        Private Sub C1PrintDocument1_PageConfigure(ByVal sender As C1.C1Preview.C1PrintDocument, ByVal e As C1.C1Preview.PageConfigureEventArgs) Handles C1PrintDocument1.PageConfigure
            If e.Page.PageNo = 3 Then
                e.PageLayout = New PageLayout
                e.PageLayout.PageHeader = New RenderText("Page header on page 3")
            End If
        End Sub
     

    But the first approach (using LayoutChange* properties) is better IMHO. Hope this helps.

     

    Cheers, Dima.
  • Dima,

    Thanks for both solutions and that works like a charm.

    Appreciate your help and quick response.

    Regards, Karthik 

     

Page 1 of 1 (5 items)