The following forum(s) are migrating to a new home on Microsoft Q&A (Preview): Developing Universal Windows apps!

Ask new questions on Microsoft Q&A (Preview).
Interact with existing posts until December 13, 2019, after which content will be closed to all new and existing posts.

Learn More

 none
UWP - Printing multiple pages RRS feed

All replies

  • Hi,

    >>Where can I find a 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 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<FrameworkElement> NeedToPrintPages;
    
       /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="scenarioPage">The scenario page constructing us</param>
            public PrintHelper(Page scenarioPage)
            {
                this.scenarioPage = scenarioPage;
                printPreviewPages = new List<UIElement>();
                NeedToPrintPages = new ObservableCollection<FrameworkElement>();
            }
    
    
           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();
            }
    
     /// <summary>
            /// This is the event handler for PrintDocument.Paginate. It creates print preview pages for the app.
            /// </summary>
            /// <param name="sender">PrintDocument</param>
            /// <param name="e">Paginate Event Arguments</param>
            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);
                }
            }
    
    
            /// <summary>
            /// This function creates and adds one print preview page to the internal cache of print preview
            /// pages stored in printPreviewPages.
            /// </summary>
            /// <param name="lastRTBOAdded">Last RichTextBlockOverflow element added in the current content</param>
            /// <param name="printPageDescription">Printer's page description</param>
            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 bold code is changed by me. You could try this in your side. When you click the print button in scenario1, it should show you two pages.

    By the way, We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!

    Best regards,

    Roy


    "Developing Universal Windows apps" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.


    Tuesday, November 5, 2019 5:59 AM
    Moderator
  • Hi,

    Does my reply help? Have you solved the problem?

    By the way, We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!

    Best regards,

    Roy


    "Developing Universal Windows apps" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.

    Tuesday, December 3, 2019 10:21 AM
    Moderator
  • Hi,

    Is my reply helpful to you? If you still have problems, please feel free to contact us.

    By the way, We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!

    Best regards,

    Roy


    "Developing Universal Windows apps" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.

    Tuesday, December 10, 2019 6:32 AM
    Moderator