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.