【问题标题】:WPF: Printing FlowDocument without Print DialogWPF:在没有打印对话框的情况下打印 FlowDocument
【发布时间】:2011-04-05 06:42:15
【问题描述】:

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

我找到了一个很好的打印示例 in this thread,但它适用于打印单个 FlowDocument,因此它使用了显示打印对话框的 CreateXpsDocumentWriter() 重载。

所以,这是我的问题:谁能提出一些好的代码来打印FlowDocument,而不显示PrintDialog?我想我会在程序开始时显示打印对话框,然后循环浏览我的笔记集合以打印每个FlowDocument。

【问题讨论】:

    标签: wpf printing flowdocument


    【解决方案1】:

    在您获得printDialog 后只需一个循环。

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

    【讨论】:

      【解决方案2】:

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

      这是一种非常简单的方法,但有一个明显的限制:它不会异步打印。为此,您必须在后台线程上执行此操作,我就是这样做的。

      【讨论】:

      • 我仍然想找到更好的方法来做到这一点。如果有人可以提出建议,我会更改已接受的答案。
      • 您可以尝试使用 PrintDialog.PrintQueue 和 PrintDialog.PrintTicket 成员。使用 PrintQueue 您可以创建一个 XpsDocumentWriter,然后您可以使用 WriteAsync() 进行异步打印。缓存队列和票似乎比缓存 PrintDialog 更好。
      • 谢谢——这很有帮助。来自我的 +1。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-25
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      相关资源
      最近更新 更多