web-dev-qa-db-fra.com

Impression d'un document WPF FlowDocument

Je construis une application de démonstration dans WPF, ce qui est nouveau pour moi. J'affiche actuellement du texte dans un FlowDocument et je dois l'imprimer.

Le code que j'utilise ressemble à ceci:

        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 est mon FlowDocument, et pour l'instant j'utilise l'imprimante par défaut au lieu de permettre à l'utilisateur de spécifier les options d'impression. Cela fonctionne correctement, sauf qu'après l'impression du document, le FlowDocument affiché à l'écran a été remplacé par les paramètres que j'ai spécifiés pour l'impression. 

Je peux résoudre ce problème en réinitialisant manuellement tout après l'impression, mais est-ce le meilleur moyen? Devrais-je faire une copie du FlowDocument avant de l’imprimer? Ou y a-t-il une autre approche à considérer?

32
Jason

oui, faites une copie du FlowDocument avant de l'imprimer. En effet, la pagination et les marges seront différentes. Cela fonctionne pour moi.

    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);
        }

    }
36
Cheeso

Vous pouvez utiliser le code de l'URL ci-dessous, il enveloppe le document de flux dans un document fixe et l'imprime, le gros avantage est que vous pouvez l'utiliser pour ajouter une marge, des en-têtes et des pieds de page.

http://blogs.msdn.com/fyuan/archive/2007/03/10/convert-xaml-flow-document-to-xps-with-style-multiple-page-page-size-header-margin. aspx

7
Nir

Ce qui suit fonctionne avec les visuels textuels et non textuels:

//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");
}
1
dotNET

Je génère également un rapport WPF à partir d'un document Flow, mais j'utilise volontairement le document Flux comme écran d'aperçu avant impression. J'y veux pour que les marges soient les mêmes. Vous pouvez lire à propos de comment j'ai fait cela ici .

Dans votre scénario, je me demande pourquoi ne pas simplement copier vos paramètres au lieu du document de flux complet. Vous pouvez ensuite réappliquer les paramètres si vous souhaitez ramener le document à son état d'origine. 

0
Allan