Combine Multiple PrintDocuments [C#]
This example shows how to combine two or more PrintDocuments into a single PrintDocument. I created a class MultiPrintDocument derived from PrintDocument. Its constructor takes an array of PrintDocument instances as a parameter.
The usage of the MultiPrintDocument class could be like this.
[C#]// suppose we need to join 3 PrintDocument instances doc1, doc2 and doc3 MultiPrintDocument multiDoc; multiDoc = new MultiPrintDocument(new PrintDocument[] { doc1, doc2, doc3 });
MultiPrintDocument overrides protected methods OnBeginPrint, OnQueryPageSettings and OnPrintPage. The overridden methods call the corresponding methods of the child documents. Note that reflection must be used to call the protected methods of child documents.
OnBeginPrint method is called before the first page of the document is printed. The overridden OnBeginPrint method resets the current document index.
OnQueryPageSettings method is called immediately before printing each page and is used for getting the PageSettings of the printed page (e.g. to check whether the page orientation is landscape or portrait). The overridden method calls OnQueryPageSettings of the current child document.
OnPrintPage is called to print a page. The overridden method calls OnPrintPage of the current child document. If it is the last page of the document, it increments the current document index and returns a value indicating that there are still other pages to print.
This is the code of the MultiPrintDocument class.
[C#]using System.Drawing.Printing; using System.Reflection; public class MultiPrintDocument : PrintDocument { private PrintDocument[] _documents; private int _docIndex; private PrintEventArgs _args; // constructors public MultiPrintDocument(PrintDocument document1, PrintDocument document2) { _documents = new PrintDocument[] { document1, document2 }; } public MultiPrintDocument(PrintDocument[] documents) { _documents = documents; } // overidden methods protected override void OnBeginPrint(PrintEventArgs e) { base.OnBeginPrint(e); if (_documents.Length == 0) e.Cancel = true; if (e.Cancel) return; _args = e; _docIndex = 0; // reset current document index CallMethod(_documents[_docIndex], "OnBeginPrint", e); } protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e) { e.PageSettings = _documents[_docIndex].DefaultPageSettings; CallMethod(_documents[_docIndex], "OnQueryPageSettings", e); base.OnQueryPageSettings(e); } protected override void OnPrintPage(PrintPageEventArgs e) { CallMethod(_documents[_docIndex], "OnPrintPage", e); base.OnPrintPage(e); if (e.Cancel) return; if (!e.HasMorePages) { CallMethod(_documents[_docIndex], "OnEndPrint", _args); if (_args.Cancel) return; _docIndex++; // increments the current document index if (_docIndex < _documents.Length) { // says that it has more pages (in others documents) e.HasMorePages = true; CallMethod(_documents[_docIndex], "OnBeginPrint", _args); } } } // use reflection to call protected methods of child documents private void CallMethod(PrintDocument document, string methodName, object args) { typeof(PrintDocument).InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, null, document, new object[] { args }); } }
See also
- PrintDocument – MSDN – class to printing documents