Printing
A WPF application with TX Text Control prints in two ways. The WPF TextControl prints the document the user sees with the print system of WPF: a printer name, a PageRange, a number of copies and a collation. ServerTextControl and MailMerge print documents that are never shown, with the PrintDocument class of System.Drawing.Printing. What follows prints documents from code without the editor: in the background, as one print job for several documents and as the result of a mail merge.
Printing the editor's document, with or without the print dialog, is covered in Print a Document and Printing and Print Preview. The code goes into MainWindow.xaml.cs with the TextControl named textControl1.
Print the Editor's Document Without a Dialog
WPF.TextControl.Print prints without a dialog when you pass it a PageRange, a number of copies and a Collation value, with or without a printer name. Print Without a Dialog in the Document Editor section shows the overloads and the code, and Connect the WPF Print Dialog passes the settings of a WPF PrintDialog to them.
Prepare the Project for PrintDocument
ServerTextControl.Print and MailMerge.Print take a System.Drawing.Printing.PrintDocument. A WPF project for .NET 8 or higher needs the NuGet package System.Drawing.Common for this class, and Print uses only some settings of the PrintDocument; Print a File Without the Editor lists them and prints a first file. MainWindow.xaml.cs needs these using directives for the rest of the examples:
using System.Drawing.Printing;
using System.Threading.Tasks;
using System.Windows;
using TXTextControl;
Print a File in the Background
A ServerTextControl doesn't belong to the window, so it can load and print a document on a thread of its own while the window keeps responding:
private async void PrintInBackground_Click(object sender, RoutedEventArgs e)
{
printInBackgroundButton.IsEnabled = false;
await Task.Run(() =>
{
using (ServerTextControl tx = new ServerTextControl())
{
// Initialize the new instance before using it
tx.Create();
tx.Load("report.docx", StreamType.WordprocessingML);
PrintDocument printDocument = new PrintDocument();
printDocument.DocumentName = "report.docx";
printDocument.PrinterSettings.PrintRange = PrintRange.SomePages;
printDocument.PrinterSettings.FromPage = 1;
printDocument.PrinterSettings.ToPage = 3;
// No status dialog of .NET
printDocument.PrintController = new StandardPrintController();
tx.Print(printDocument);
}
});
// The code after await runs on the UI thread again
printInBackgroundButton.IsEnabled = true;
}
The code works as follows:
- Create initializes the ServerTextControl; the
usingblock disposes it after printing. PrintRange.SomePagesmakesPrintuseFromPageandToPage.- A
StandardPrintControllersuppresses the dialog with the page being printed. - The WPF
TextControlbelongs to the UI thread and isn't used insideTask.Run. To print its document in the background, save it to a byte array first, as Using ServerTextControl in Desktop Applications shows.
Print Several Documents in One Print Job
ServerTextControl.Print(int page, PrintPageEventArgs e) prints one page from the PrintPage event of a PrintDocument. With it, several documents go to the printer as a single job:
private void PrintBatch_Click(object sender, RoutedEventArgs e)
{
string[] files = { "letter.docx", "invoice.docx" };
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
int fileIndex = 0;
int pageNumber = 1;
tx.Load(files[fileIndex], StreamType.WordprocessingML);
PrintDocument printDocument = new PrintDocument();
printDocument.DocumentName = "Letter and invoice";
printDocument.PrintController = new StandardPrintController();
printDocument.PrintPage += (s, args) =>
{
tx.Print(pageNumber, args);
pageNumber++;
// Last page of this file: continue with the next file
if (pageNumber > tx.Pages)
{
fileIndex++;
if (fileIndex < files.Length)
{
tx.Load(files[fileIndex], StreamType.WordprocessingML);
pageNumber = 1;
}
}
args.HasMorePages = fileIndex < files.Length;
};
printDocument.Print();
}
}
printDocument.Print() starts the job, .NET raises PrintPage once per page, and HasMorePages is false after the last page of the last file. ServerTextControl.Pages is the number of pages of the loaded document.
Print a Merged Document
A MailMerge connected to a ServerTextControl merges a template with data and prints the result with MailMerge.Print, which takes either a PrintDocument or a document name, a printer name, a number of copies and a collate flag. Load, Save and Print With MailMerge shows the code, with the printer chosen in the WPF print dialog.
Choose the Formatting Printer
Line and page breaks depend on the printer whose text measurements TX Text Control uses, as Print Exactly What the Screen Shows explains. ServerTextControl.FormattingPrinter takes the same values as WPF.TextControl.FormattingPrinter: a printer name, "Standard" or "Display". Give the TextControl and the ServerTextControl the same value when documents move between them. A network printer that answers slowly can delay the initialization of TX Text Control; the blog article Initialize Text Control Without a Printer (Completely) describes this.
Next Steps
- Printing and Print Preview: printing from the editor with the print dialog.
- Printing in Troubleshooting: disabled printing and unexpected breaks.
- Using ServerTextControl in Desktop Applications: background work with
ServerTextControl. - Sections, Pages, Headers, and Footers: pages and page numbers.