David Veeneman
David Veeneman

Reputation: 19132

WPF: Printing FlowDocument without Print Dialog

I am writing a note-taking application in WPF, using a FlowDocument for each individual note. The app searches and filters notes by tags. I want to print all notes in the current filtered list as separate documents, and I only want to show a single Print Dialog at the beginning of the job.

I found a good print example in this thread, but it is geared toward printing a single FlowDocument, so it uses a CreateXpsDocumentWriter() overload that displays a Print Dialog.

So, here's my question: Can anyone suggest some good code for printing a FlowDocument without displaying a PrintDialog? I figure I'll display the Print Dialog at the beginning of the procedure and then loop through my notes collection to print each FlowDocument.

Upvotes: 6

Views: 5000

Answers (2)

hotter
hotter

Reputation: 11

Just a loop after you have got the printDialog.

for(int i=0 i<document.count i++)
    printdocument((document[i] as iDocumentPaginator),"title"+[i]);

Upvotes: 1

David Veeneman
David Veeneman

Reputation: 19132

I have rewritten my answer to this question, because I did find a better way to print a set of FlowDocuments, while showing the Print Dialog only once. The answer comes from MacDonald, Pro WPF in C# 2008 (Apress 2008) in Chapter 20 at p. 704.

My code bundles a set of Note objects into an IList called notesToPrint and gets the FlowDocument for each Note from a DocumentServices class in my app. It sets the FlowDocument boundaries to match the printer and sets a 1-inch margin. Then it prints the FlowDocument, using the document's DocumentPaginator property. Here's the code:

// Show Print Dialog
var printDialog = new PrintDialog();
var userCanceled = (printDialog.ShowDialog() == false);
if(userCanceled) return;

// Print Notes
foreach(var note in notesToPrint)
{
    // Get next FlowDocument
    var collectionFolderPath = DataStore.CollectionFolderPath;
    var noteDocument = DocumentServices.GetFlowDocument(note, collectionFolderPath) ;

    // Set the FlowDocument boundaries to match the page
    noteDocument.PageHeight = printDialog.PrintableAreaHeight;
    noteDocument.PageWidth = printDialog.PrintableAreaWidth;

    // Set margin to 1 inch
    noteDocument.PagePadding = new Thickness(96);

    // Get the FlowDocument's DocumentPaginator
    var paginatorSource = (IDocumentPaginatorSource)noteDocument;
    var paginator = paginatorSource.DocumentPaginator;

    // Print the Document
    printDialog.PrintDocument(paginator, "FS NoteMaster Document");
}

This is a pretty simple approach, with one significant limitation: It doesn't print asynchronously. To do that, you would have to perform this operation on a background thread, which is how I do it.

Upvotes: 3

Related Questions