| « Alternating row styles in a ListBox | Background printing with FlowDocumentScrollViewer » |
More Than Meets the Eye
You may have glossed over the following code in my previous post:
PrintTicket ticket = new PrintTicket();
ticket.PageOrientation = PageOrientation.Portrait;
ticket.CopyCount = copies;
PrintCapabilities capabilities = queue.GetPrintCapabilities(ticket);
...
writer.WriteAsync(documentPaginator, ticket);
And I couldn't blame you for it. On the surface it doesn't appear all that significant or interesting.
But the reason behind creating and using a custom PrintTicket goes beyond setting the number of copies for the print job.
Oww, My Print Driver!
You may encounter the following exception with certain print drivers if you do not use your own PrintTicket:
System.Printing.PrintQueueException:
"PrintTicket provider failed to retrieve PrintCapabilities. Win32 error: -2147467259"
If you do not specify your own PrintTicket for print operations, the default UserPrintTicket for the PrintQueue is used, and some print drivers fail to provide valid objects for the UserPrintTicket and DefaultPrintTicket by yielding the above exception. This is essentially a driver problem, but inevitably there will be instances where your software runs on drivers you didn't know about or in environments where driver upgrades may not be possible.
My Recommendation
Therefore, I recommend always forcing use of your own PrintTicket for all printing operations in WPF, as I did in the above code for the calls to GetPrintCapabilities and WriteAsync methods. Note that each of these methods has an overload that does not take a PrintTicket argument. These are the ones to avoid.
Alternatively...
You can also set the value of the UserPrintTicket property on the PrintQueue, thus overriding the default UserPrintTicket with your own. Then you can omit the ticket argument to subsequent print method calls.
This post has 739 feedbacks awaiting moderation...