WPF:如何在不弹出打印对话框的情况下打印FlowDocument

6
我正在使用WPF编写一个笔记应用程序,为每个单独的笔记使用FlowDocument。该应用程序通过标签搜索和过滤笔记。我希望将当前过滤列表中的所有笔记作为单独的文档打印,并且只想在作业开始时显示一个单独的打印对话框。
我在这个线程中找到了一个很好的打印示例,但它针对打印单个FlowDocument,因此使用了一个显示打印对话框的CreateXpsDocumentWriter()重载。
所以,我的问题是:有人可以建议一些好的代码来打印FlowDocument而不显示PrintDialog吗? 我打算在过程开始时显示打印对话框,然后循环遍历我的笔记集合以打印每个FlowDocument
2个回答

3

我已经重新编写了对这个问题的回答,因为我找到了一种更好的方法来打印一组FlowDocuments,同时只显示一次打印对话框。这个答案来自MacDonald在他的书《Pro WPF in C# 2008》(Apress 2008)的第20章,第704页。

我的代码将一组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");
}

这是一个相当简单的方法,但有一个重要的限制:它不能异步打印。如果要实现异步打印,您需要在后台线程上执行此操作,这就是我如何做到的。


我仍然希望找到更好的方法来做这件事。如果有人能提出建议,我会改变接受的答案。 - David Veeneman
3
你可以尝试使用PrintDialog.PrintQueue和PrintDialog.PrintTicket成员。使用PrintQueue,你可以创建一个XpsDocumentWriter,然后使用WriteAsync()进行异步打印。缓存队列和票据似乎比缓存PrintDialog更好。 - Pablo Montilla
谢谢,这很有帮助。我给你点赞。 - David Veeneman

1

在获取了printDialog之后,只需要一个循环即可。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接