UWP - Printing multiple pages

Roy Li - MSFT 33,451 Reputation points Microsoft Vendor
2019-12-12T09:11:25.523+00:00

Source link: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/6145a17f-79f2-4777-9229-05ee623212ff/uwp-printing-multiple-pages?forum=wpdevelop

How can I find an easy to understand sample for printing multiple pages on UWP, say printing 2 pages.

Universal Windows Platform (UWP)
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Roy Li - MSFT 33,451 Reputation points Microsoft Vendor
    2019-12-12T09:18:40.387+00:00

    Hello,

    Welcome to MicrosoftQ&A!

    >>How can I find an easy to understand sample for printing multiple pages on UWP, say printing 2 pages.

    There is a document about printing here: Print from your app. And here is the printing Sample.

    Both the sample and the document shows how to print one page. So you will need to change the sample code a little bit to print more than one page.

    In scenario 1, the basic print function, when you want to print a page, you will need to call the PreparePrintContent() method in the codebehind to initialize print content. Then when you try to show the print preview, it will trigger PrintDocument.Paginate Event, in that event handler you can prepare the content that needs to be printed. And you will need to do most of the changes in this event handler.

    I've modified the sample to print two pages.

    In sceario1 basic.cs:

     protected override void OnNavigatedTo(NavigationEventArgs e)  
            {  
               ...some other codes...  
                // Initalize common helper class and register for printing  
                printHelper = new PrintHelper(this);  
                printHelper.RegisterForPrinting();  
      
                // Initialize print content for this scenario  
                printHelper.PreparePrintContent(new PageToPrint());  
                //add another page to print. It's a copy of the previous page.  
                printHelper.PreparePrintContent(new NewPage());  
            }  
    

    In printHelper.cs:

       // collection for multiple pages  
            **protected ObservableCollection NeedToPrintPages;**  
      
       ///   
            /// Constructor  
            ///   
            /// The scenario page constructing us  
            public PrintHelper(Page scenarioPage)  
            {  
                this.scenarioPage = scenarioPage;  
                printPreviewPages = new List();  
                **NeedToPrintPages = new ObservableCollection();**  
            }  
      
      
           public virtual void PreparePrintContent(Page page)  
            {  
                //if (firstPage == null)  
                //{  
                    //firstPage = page;  
                    **FrameworkElement tempPage = page;**  
                    **StackPanel header = (StackPanel)tempPage.FindName("Header");**  
                    header.Visibility = Windows.UI.Xaml.Visibility.Visible;  
                //}  
      
                **NeedToPrintPages.Add(tempPage);**  
                // Add the (newly created) page to the print canvas which is part of the visual tree and force it to go  
                // through layout so that the linked containers correctly distribute the content inside them.  
                PrintCanvas.Children.Add(tempPage);  
                PrintCanvas.InvalidateMeasure();  
                PrintCanvas.UpdateLayout();  
            }  
      
     ///   
            /// This is the event handler for PrintDocument.Paginate. It creates print preview pages for the app.  
            ///   
            /// PrintDocument  
            /// Paginate Event Arguments  
            protected virtual void CreatePrintPreviewPages(object sender, PaginateEventArgs e)  
            {  
                lock (printPreviewPages)  
                {  
                      
                    // Clear the cache of preview pages  
                    printPreviewPages.Clear();  
      
                    // Clear the print canvas of preview pages  
                    PrintCanvas.Children.Clear();  
      
                    **for (int i= 0; i< NeedToPrintPages.Count; i++)**  
                    {  
                        // This variable keeps track of the last RichTextBlockOverflow element that was added to a page which will be printed  
                        RichTextBlockOverflow lastRTBOOnPage;  
      
                        // Get the PrintTaskOptions  
                        PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);  
      
                        // Get the page description to deterimine how big the page is  
                        PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);  
      
                        // We know there is at least one page to be printed. passing null as the first parameter to  
                        // AddOnePrintPreviewPage tells the function to add the first page.  
                        **lastRTBOOnPage = AddOnePrintPreviewPage(null, pageDescription,i);**  
      
                        // We know there are more pages to be added as long as the last RichTextBoxOverflow added to a print preview  
                        // page has extra content  
                        while (lastRTBOOnPage.HasOverflowContent && lastRTBOOnPage.Visibility == Windows.UI.Xaml.Visibility.Visible)  
                        {  
                            **lastRTBOOnPage = AddOnePrintPreviewPage(lastRTBOOnPage, pageDescription,i);**  
                        }  
      
                    }  
                      
      
                    if (PreviewPagesCreated != null)  
                    {  
                        PreviewPagesCreated.Invoke(printPreviewPages, null);  
                    }  
      
                    PrintDocument printDoc = (PrintDocument)sender;  
      
                    // Report the number of preview pages created  
                    printDoc.SetPreviewPageCount(printPreviewPages.Count, PreviewPageCountType.Intermediate);  
                }  
            }  
      
      
            ///   
            /// This function creates and adds one print preview page to the internal cache of print preview  
            /// pages stored in printPreviewPages.  
            ///   
            /// Last RichTextBlockOverflow element added in the current content  
            /// Printer's page description  
            protected virtual RichTextBlockOverflow AddOnePrintPreviewPage(RichTextBlockOverflow lastRTBOAdded, PrintPageDescription printPageDescription,int index)  
            {  
                // XAML element that is used to represent to "printing page"  
                FrameworkElement page;  
      
                // The link container for text overflowing in this page  
                RichTextBlockOverflow textLink;  
      
                // Check if this is the first page ( no previous RichTextBlockOverflow)  
                if (lastRTBOAdded == null)  
                {  
                    // If this is the first page add the specific scenario content  
                    **page = NeedToPrintPages[index];**  
      
                    // Hide footer since we don't know yet if it will be displayed (this might not be the last page) - wait for layout  
                    StackPanel footer = (StackPanel)page.FindName("Footer");  
                    footer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;  
                }  
                else  
                {  
                    // Flow content (text) from previous pages  
                    page = new ContinuationPage(lastRTBOAdded);  
                }  
      
                // Set "paper" width  
                **page.Width = printPageDescription.PageSize.Width;**  
                **page.Height = printPageDescription.PageSize.Height;**  
                  
                Grid printableArea = (Grid)page.FindName("PrintableArea");  
      
                // Get the margins size  
                // If the ImageableRect is smaller than the app provided margins use the ImageableRect  
                double marginWidth = Math.Max(printPageDescription.PageSize.Width - printPageDescription.ImageableRect.Width, printPageDescription.PageSize.Width * ApplicationContentMarginLeft * 2);  
                double marginHeight = Math.Max(printPageDescription.PageSize.Height - printPageDescription.ImageableRect.Height, printPageDescription.PageSize.Height * ApplicationContentMarginTop * 2);  
      
                // Set-up "printable area" on the "paper"  
                printableArea.Width = NeedToPrintPages[index].Width - marginWidth;  
                printableArea.Height = NeedToPrintPages[index].Height - marginHeight;  
      
                // Add the (newley created) page to the print canvas which is part of the visual tree and force it to go  
                // through layout so that the linked containers correctly distribute the content inside them.  
                PrintCanvas.Children.Add(page);  
                PrintCanvas.InvalidateMeasure();  
                PrintCanvas.UpdateLayout();  
      
                // Find the last text container and see if the content is overflowing  
                textLink = (RichTextBlockOverflow)page.FindName("ContinuationPageLinkedContainer");  
      
                // Check if this is the last page  
                if (!textLink.HasOverflowContent && textLink.Visibility == Windows.UI.Xaml.Visibility.Visible)  
                {  
                    StackPanel footer = (StackPanel)page.FindName("Footer");  
                    footer.Visibility = Windows.UI.Xaml.Visibility.Visible;  
                    PrintCanvas.UpdateLayout();  
                }  
      
                // Add the page to the page preview collection  
                printPreviewPages.Add(page);  
      
                return textLink;  
            }  
    

    The code with the '**' tag is changed by me. You could try this on your side. When you click the print button in scenario1, it should show you two pages.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.