38 votes

Impression d'un WPD FlowDocument

Je suis en train de construire une démo d'application en WPF, ce qui est nouveau pour moi. Je suis actuellement à l'affichage du texte dans un FlowDocument, et le besoin de 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 je suis à l'aide de l'imprimante par défaut au lieu de permettre à l'utilisateur de spécifier les options d'impression. Cela fonctionne bien, sauf qu'après l'impression du document, le FlowDocument affichés sur l'écran a changé pour utiliser les paramètres que j'ai spécifié pour l'impression.

Je peux résoudre ce problème par la main de tout réinitialiser après j'ai l'impression, mais est-ce la meilleure façon de faire? Dois-je faire une copie de la FlowDocument avant que je imprimer? Ou est-il une autre approche que je devrais envisager?

41voto

Cheeso Points 87022

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

    }
 

8voto

Nir Points 18250

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

0voto

Allan Points 113

Je suis aussi de la génération d'un WPF rapport à partir d'un Flux de documents, mais je suis volontairement en utilisant le flux de document comme une impression de l'écran de prévisualisation. J'y veux les marges être le même. Vous pouvez lire au sujet de la façon dont je l'ai fait ici.

Dans votre scénario, je pense, pourquoi ne pas simplement faire une copie de vos paramètres, au lieu de l'ensemble des flux de documents. Vous pouvez appliquer les paramètres si vous souhaitez retourner le document de retour à son état d'origine.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X