2010-08-28 3 views
6

J'écris une application de prise de notes dans WPF, en utilisant un FlowDocument pour chaque note individuelle. L'application recherche et filtre les notes par tags. Je souhaite imprimer toutes les notes de la liste filtrée en cours en tant que documents distincts et je souhaite uniquement afficher une seule boîte de dialogue Imprimer au début du travail.WPF: Impression de FlowDocument sans dialogue d'impression

J'ai trouvé un bon exemple d'impression in this thread, mais il est conçu pour imprimer un seul FlowDocument, donc il utilise une surcharge CreateXpsDocumentWriter() qui affiche une boîte de dialogue Imprimer. Donc, voici ma question: Quelqu'un peut-il suggérer un bon code pour imprimer un FlowDocument sans afficher un PrintDialog? Je suppose que je vais afficher la boîte de dialogue Imprimer au début de la procédure, puis boucle dans ma collection de notes pour imprimer chaque FlowDocument.

Répondre

3

J'ai réécrit ma réponse à cette question, car j'ai trouvé une meilleure façon d'imprimer un ensemble de FlowDocuments, tout en affichant la boîte de dialogue Imprimer une seule fois. La réponse vient de MacDonald, Pro WPF dans C# 2008 (Apress 2008) dans le chapitre 20 à la p. 704.

Mon code regroupe un ensemble d'objets Note dans un IList appelé notesToPrint et obtient le FlowDocument pour chaque note d'une classe DocumentServices dans mon application. Il définit les limites FlowDocument pour correspondre à l'imprimante et définit une marge de 1 pouce. Ensuite, il imprime le FlowDocument en utilisant la propriété DocumentPaginator du document. Voici le 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"); 
} 

Ceci est une approche assez simple, avec une limitation importante: Elle n'imprime pas de façon asynchrone. Pour ce faire, vous devez effectuer cette opération sur un thread d'arrière-plan, ce qui est la façon dont je le fais.

+0

J'aimerais toujours trouver une meilleure façon de le faire. Si quelqu'un peut en suggérer un, je vais changer la réponse acceptée. –

+3

Vous pouvez essayer d'utiliser les membres PrintDialog.PrintQueue et PrintDialog.PrintTicket. Avec PrintQueue vous pouvez créer un XpsDocumentWriter, puis vous pouvez utiliser WriteAsync() pour imprimer de manière asynchrone. La mise en cache de la file d'attente et du ticket semble préférable à la mise en cache du PrintDialog. –

+0

Merci - c'est utile. +1 de moi. –

1

Juste une boucle après avoir obtenu le printDialog.

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