2008-12-05 198 views
32

我正在WPF中构建一个演示应用程序,这对我来说是新的。我目前在FlowDocument中显示文本,并需要打印它。打印WPF FlowDocument

的代码我使用看起来像这样:

 PrintDialog pd = new PrintDialog(); 
     fd.PageHeight = pd.PrintableAreaHeight; 
     fd.PageWidth = pd.PrintableAreaWidth; 
     fd.PagePadding = new Thickness(50); 
     fd.ColumnGap = 0; 
     fd.ColumnWidth = pd.PrintableAreaWidth; 

     IDocumentPaginatorSource dps = fd; 
     pd.PrintDocument(dps.DocumentPaginator, "flow doc"); 

fd是我的FlowDocument,现在来看我使用默认打印机,而不是允许用户指定打印选项。它工作正常,除了在文档打印之后,屏幕上显示的FlowDocument已更改为使用我指定用于打印的设置。

我可以通过在打印后手动重置所有内容来解决此问题,但这是最佳方式吗?我应该在打印之前制作FlowDocument的副本吗?或者我应该考虑另一种方法?

+8

你的问题是我的回答。谢谢! – BrokeMyLegBiking 2013-04-10 13:24:02

回答

35

是,在打印之前进行的FlowDocument的副本。这是因为分页和边距会有所不同。这对我有用。

private void DoThePrint(System.Windows.Documents.FlowDocument document) 
    { 
     // Clone the source document's content into a new FlowDocument. 
     // This is because the pagination for the printer needs to be 
     // done differently than the pagination for the displayed page. 
     // We print the copy, rather that the original FlowDocument. 
     System.IO.MemoryStream s = new System.IO.MemoryStream(); 
     TextRange source = new TextRange(document.ContentStart, document.ContentEnd); 
     source.Save(s, DataFormats.Xaml); 
     FlowDocument copy = new FlowDocument(); 
     TextRange dest = new TextRange(copy.ContentStart, copy.ContentEnd); 
     dest.Load(s, DataFormats.Xaml); 

     // Create a XpsDocumentWriter object, implicitly opening a Windows common print dialog, 
     // and allowing the user to select a printer. 

     // get information about the dimensions of the seleted printer+media. 
     System.Printing.PrintDocumentImageableArea ia = null; 
     System.Windows.Xps.XpsDocumentWriter docWriter = System.Printing.PrintQueue.CreateXpsDocumentWriter(ref ia); 

     if (docWriter != null && ia != null) 
     { 
      DocumentPaginator paginator = ((IDocumentPaginatorSource)copy).DocumentPaginator; 

      // Change the PageSize and PagePadding for the document to match the CanvasSize for the printer device. 
      paginator.PageSize = new Size(ia.MediaSizeWidth, ia.MediaSizeHeight); 
      Thickness t = new Thickness(72); // copy.PagePadding; 
      copy.PagePadding = new Thickness(
          Math.Max(ia.OriginWidth, t.Left), 
           Math.Max(ia.OriginHeight, t.Top), 
           Math.Max(ia.MediaSizeWidth - (ia.OriginWidth + ia.ExtentWidth), t.Right), 
           Math.Max(ia.MediaSizeHeight - (ia.OriginHeight + ia.ExtentHeight), t.Bottom)); 

      copy.ColumnWidth = double.PositiveInfinity; 
      //copy.PageWidth = 528; // allow the page to be the natural with of the output device 

      // Send content to the printer. 
      docWriter.Write(paginator); 
     } 

    } 
+4

这似乎只能打印文本,您如何打印BlockUIContainer? – Beaker 2009-05-26 19:20:08

+0

@Beaker看看这个解决方案,允许您打印图像和其他BlockUIcontainer:http://stackoverflow.com/a/18088609/1243372 – 2013-08-06 19:18:07

0

我也产生一个WPF报告过流文件,但我故意使用流文档的打印预览画面。我在那里希望边际保持一致。你可以阅读关于how I did this here

在你的场景中,我想为什么不直接复制你的设置,而不是整个流程文档。如果您希望将文档恢复到原始状态,您可以重新应用这些设置。

0

与文本和非文本的视觉效果以下工作:

//Clone the source document 
var str = XamlWriter.Save(FlowDoc); 
var stringReader = new System.IO.StringReader(str); 
var xmlReader = XmlReader.Create(stringReader); 
var CloneDoc = XamlReader.Load(xmlReader) as FlowDocument; 

//Now print using PrintDialog 
var pd = new PrintDialog(); 

if (pd.ShowDialog().Value) 
{ 
    CloneDoc.PageHeight = pd.PrintableAreaHeight; 
    CloneDoc.PageWidth = pd.PrintableAreaWidth; 
    IDocumentPaginatorSource idocument = CloneDoc as IDocumentPaginatorSource; 

    pd.PrintDocument(idocument.DocumentPaginator, "Printing FlowDocument"); 
}