/// <summary> /// Prepare print content and send it to the Printing Root. /// </summary> private void PreparePrintContent() { // Create and populate print page. var printPage = Activator.CreateInstance(this.printPageType) as Page; printPage.DataContext = this.DataContext; // Create print template page and fill invisible textblock with empty paragraph. // This pushes all real content into the overflow. firstPage = new PrintPage(); firstPage.AddContent(new Paragraph()); // Move content from print page to print template - paragraph by paragraph. var printPageRtb = printPage.Content as RichTextBlock; while (printPageRtb.Blocks.Count > 0) { var paragraph = printPageRtb.Blocks.First() as Paragraph; printPageRtb.Blocks.Remove(paragraph); var container = paragraph.Inlines[0] as InlineUIContainer; if (container != null) { // Place the paragraph in a new textblock, and measure it. var measureRtb = new RichTextBlock(); measureRtb.Blocks.Add(paragraph); PrintingRoot.Children.Clear(); PrintingRoot.Children.Add(measureRtb); PrintingRoot.InvalidateMeasure(); PrintingRoot.UpdateLayout(); measureRtb.Blocks.Remove(paragraph); // Apply line height to trigger overflow. paragraph.LineHeight = measureRtb.ActualHeight; } firstPage.AddContent(paragraph); }; // Send it to the printing root. PrintingRoot.Children.Clear(); PrintingRoot.Children.Add(firstPage); }
/// <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> private RichTextBlockOverflow AddOnePrintPreviewPage(RichTextBlockOverflow lastRTBOAdded, PrintPageDescription printPageDescription) { // 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 = firstPage; } else { // Flow content (text) from previous pages page = new PrintPage(lastRTBOAdded); // Remove the duplicate OverflowContentTarget. ((RichTextBlock)page.FindName("textContent")).OverflowContentTarget = null; } // 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 * HorizontalPrintMargin * 2); double marginHeight = Math.Max(printPageDescription.PageSize.Height - printPageDescription.ImageableRect.Height, printPageDescription.PageSize.Height * VerticalPrintMargin * 2); // Set-up "printable area" on the "paper" printableArea.Width = page.Width - marginWidth; printableArea.Height = page.Height - marginHeight; // Add the (newly created) page to the printing root 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. PrintingRoot.Children.Add(page); PrintingRoot.InvalidateMeasure(); PrintingRoot.UpdateLayout(); // Find the last text container and see if the content is overflowing textLink = (RichTextBlockOverflow)page.FindName("continuationPageLinkedContainer"); // Add page number this.pageNumber += 1; TextBlock pageNumberTextBlock = (TextBlock)page.FindName("pageNumber"); if (pageNumberTextBlock != null) { pageNumberTextBlock.Text = string.Format("- {0} -", this.pageNumber); } // Add the page to the page preview collection printPreviewPages.Add(page); return textLink; }