2008-12-05 40 views
32

Estoy construyendo una aplicación de demostración en WPF, que es nueva para mí. Actualmente estoy mostrando texto en un FlowDocument y necesito imprimirlo.Imprimir un WPF FlowDocument

El código que estoy usando el siguiente aspecto:

 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 es mi FlowDocument, y por ahora estoy usando la impresora por defecto en lugar de permitir al usuario especificar las opciones de impresión. Funciona bien, excepto que después de que se imprime el documento, el FlowDocument que se muestra en la pantalla ha cambiado a para usar la configuración que especifiqué para imprimir.

Puedo solucionar esto restableciendo manualmente todo después de imprimir, pero ¿es esta la mejor manera? ¿Debo hacer una copia del FlowDocument antes de imprimirlo? ¿O hay otro enfoque que debería considerar?

+8

Su pregunta fue mi respuesta. ¡Gracias! – BrokeMyLegBiking

Respuesta

35

sí, hacer una copia de la FlowDocument antes de imprimirlo. Esto se debe a que la paginación y los márgenes serán diferentes. Esto funciona para mí

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

Esto solo parece imprimir texto, ¿cómo se imprime un BlockUIContainer? – Beaker

+0

@Beaker Vea esta solución que le permite imprimir imágenes y otros BlockUIcontainer: http://stackoverflow.com/a/18088609/1243372 –

0

También estoy generando un informe de WPF fuera un documento de flujo, pero estoy usando a propósito del documento de flujo como una pantalla de vista previa de impresión. Quiero que los márgenes sean los mismos. Puedes leer sobre how I did this here.

En su escenario, estoy pensando por qué no solo hace una copia de su configuración, en lugar de todo el documento de flujo. Luego puede volver a aplicar la configuración si desea devolver el documento a su estado original.

+0

link broken - :( – TravisWhidden

+0

He reparado el enlace en esta respuesta usando WayBackMachine. http://www.archive.org/index.php – Dennis

0

Los siguientes sirve para las representaciones visuales de texto y no textuales:

//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"); 
} 
Cuestiones relacionadas