简体   繁体   中英

WPF PrintPreview Get the PageContent of DocumentPaginator Pages

I want to write my own PrintPreview for larger text using a DocumentViewer to display it later. I have not found anything usefully for my problem.

At the moment I'm searching for a way to get the content of the individual pages. I found a way to access the individual pages, but I can't store or get it.

Using the code:

  DocumentPaginator dpPages = (DocumentPaginator)((IDocumentPaginatorSource)twhtTemp.BuildTemplateControl(txtHeader, txtContent, pdlgPrint)).DocumentPaginator;
            dpPages.ComputePageCount();

            var fixedDocument = new FixedDocument();

            for (int iPages= 0; iPages < dpPages.PageCount; iPages++)
            {
                
                var pageContent = new PageContent();
                var fixedPage = new FixedPage();


                fixedPage.Width = pdlgPrint.PrintableAreaWidth;
                fixedPage.Height = pdlgPrint.PrintableAreaHeight;
                pageContent.Child = fixedPage;
                fixedDocument.Pages.Add(pageContent);
            }

I'm already adding a new page for each existing page, but I can't get the content of the page.
So far I know, I need a UIElement to add to fixedPage.Children .

Or is there some easier way to get a flowdocument to a fixed document with many fixedpages (deppending to the pages count)?

i hate it to answer my own questions.
After searching three days i asked here.
One day later i found a way...

It's been a long time since the question has been answered.
I tried Doo Dah's answer, but the problem was that it doesn't take care of the page paddings of a flowdocument.

Therefore I wrote my own solution (Doo Dah's answer helped me to complete it):

 public FixedDocument Get_Fixed_From_FlowDoc(FlowDocument flowDoc, PrintDialog printDlg)
{
           var fixedDocument = new FixedDocument();
            try
            {
                if (printDlg != null)
                {
                    pdlgPrint = printDlg;
                }

            if (pdlgPrint == null)
            {
                pdlgPrint = new PrintDialog();
            }

            DocumentPaginator dpPages = (DocumentPaginator)((IDocumentPaginatorSource)flowDoc).DocumentPaginator;
            dpPages.ComputePageCount();
            PrintCapabilities capabilities = pdlgPrint.PrintQueue.GetPrintCapabilities(pdlgPrint.PrintTicket);
           

            for (int iPages= 0; iPages < dpPages.PageCount; iPages++)
            {

                var page = dpPages.GetPage(iPages);
                var pageContent = new PageContent();
                var fixedPage = new FixedPage();


                Canvas canvas = new Canvas();

                VisualBrush vb = new VisualBrush(page.Visual);
                vb.Stretch = Stretch.None;
                vb.AlignmentX = AlignmentX.Left;
                vb.AlignmentY = AlignmentY.Top;
                vb.ViewboxUnits = BrushMappingMode.Absolute;
                vb.TileMode = TileMode.None;
                vb.Viewbox = new Rect(0, 0, capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);


                FixedPage.SetLeft(canvas, 0);
                FixedPage.SetTop(canvas, 0);
                canvas.Width = capabilities.PageImageableArea.ExtentWidth;
                canvas.Height = capabilities.PageImageableArea.ExtentHeight;
                canvas.Background = vb;

                fixedPage.Children.Add(canvas);

                fixedPage.Width = pdlgPrint.PrintableAreaWidth;
                fixedPage.Height = pdlgPrint.PrintableAreaHeight;
                pageContent.Child = fixedPage;
                fixedDocument.Pages.Add(pageContent);
            }
            dv1.ShowPageBorders = true;

        }
        catch (Exception)
        {
            throw;
        }
        return fixedDocument;
    }

You had to build a FlowDocument of the content you will show before and pass it to the Method.
Added the PrintDialog variable to call the Method from my preview window and can pass the current printer settings.

If you call it from your main programm, you either can pass a new PrintDialog() or null , there is no difference, because it will create a new PrintDialog if you are passing null

This worked fine for me with a Flowdocument with different types of text (header, text, font).

It should work with pictures and text mixed, or only pictures, too - it's using the visuals and not something specific from a flowdocument, therefore it should work with pagebreaks, too.

I don't tryed Shahin Dohan'S answer, because it's the same problem as so often.
It's written at MVVM and very hard to understand when another person has written it.
At my opinion it would be better to write a little example programm without mvvm and the people can adept it to mvvm or use only the code.
I understand the opportunities of mvvm, but to show someone how to works something i see only disadvantages (if you will not show a specific mvvm mechanic)

Is it possible in WPF to get content of each DocumentPage by page number?

You can follow this then add each extracted TextRange to whatever you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM