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
GeneratePages()
AddHeader1()
AddHeader2()
AddHeader3()
C1PrintDocument1.Body.Children.Add(objTable)
objTable =
C1PrintDocument1.Reflow()
objTable.Cells(0, 0).Text =
objTable.Style.BackColor = Color.LightGray
objTable.Style.BackColor = Color.LightCoral
objTable.Style.BackColor = Color.LightYellow
End
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
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.
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.
Thanks for both solutions and that works like a charm.
Appreciate your help and quick response.