WPF:打印没有打印对话框的FlowDocument

时间:2022-10-30 21:27:05

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.

我正在WPF中写一个笔记记录应用程序,为每个单独的笔记使用FlowDocument。该应用按标签搜索和过滤笔记。我想将当前筛选列表中的所有笔记打印为单独的文档,我只想在作业开头显示一个打印对话框。

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.

我在这个帖子中找到了一个很好的打印示例,但是它适用于打印单个FlowDocument,因此它使用CreateXpsDocumentWriter()重载来显示打印对话框。

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.

所以,这是我的问题:有人可以建议一些好的代码来打印FlowDocument而不显示PrintDialog吗?我想我将在程序开始时显示Print Dialog,然后循环我的notes集合以打印每个FlowDocument。

2 个解决方案

#1


3  

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.

我已经重写了我对这个问题的回答,因为我确实找到了一种更好的方法来打印一组FlowDocuments,同时只显示一次Print Dialog。答案来自MacDonald,Pro WPF in C#2008(Apress 2008),第20章,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:

我的代码将一组Note对象捆绑到名为notesToPrint的IList中,并从我的应用程序中的DocumentServices类获取每个Note的FlowDocument。它设置FlowDocument边界以匹配打印机并设置1英寸的边距。然后使用文档的DocumentPaginator属性打印FlowDocument。这是代码:

// 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.

这是一个非常简单的方法,有一个显着的限制:它不会异步打印。要做到这一点,你必须在后台线程上执行此操作,这就是我的工作方式。

#2


1  

Just a loop after you have got the printDialog.

获得printDialog后只需一个循环。

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

#1


3  

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.

我已经重写了我对这个问题的回答,因为我确实找到了一种更好的方法来打印一组FlowDocuments,同时只显示一次Print Dialog。答案来自MacDonald,Pro WPF in C#2008(Apress 2008),第20章,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:

我的代码将一组Note对象捆绑到名为notesToPrint的IList中,并从我的应用程序中的DocumentServices类获取每个Note的FlowDocument。它设置FlowDocument边界以匹配打印机并设置1英寸的边距。然后使用文档的DocumentPaginator属性打印FlowDocument。这是代码:

// 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.

这是一个非常简单的方法,有一个显着的限制:它不会异步打印。要做到这一点,你必须在后台线程上执行此操作,这就是我的工作方式。

#2


1  

Just a loop after you have got the printDialog.

获得printDialog后只需一个循环。

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