/// <summary> /// Creates a print preview page and adds it to the internal list. /// </summary> private RichTextBlockOverflow AddOnePrintPreviewPage(RichTextBlockOverflow lastOverflowAdded, PrintPageDescription printPageDescription) { PrintPage printPage; // Check if this is the first page. if (lastOverflowAdded == null) { printPage = _firstPrintPage; } else { // Flow content from previous pages. printPage = new PrintPage(lastOverflowAdded); // Remove the duplicate OverflowContentTarget. printPage.TextContent.OverflowContentTarget = null; } // Set page size. ApplyPrintPageDescription(printPageDescription, printPage); // Add title. var titleTextBlock = (TextBlock)printPage.FindName("title"); if (titleTextBlock != null) { titleTextBlock.Text = Title; } // Add page number _pageNumber += 1; var pageNumberTextBlock = (TextBlock)printPage.FindName("pageNumber"); if (pageNumberTextBlock != null) { pageNumberTextBlock.Text = string.Format("- {0} -", _pageNumber); } // Add the page to the page preview collection _printPreviewPages.Add(printPage); // The link container for text overflowing in this page return(printPage.TextOverflow); }
/// <summary> /// Prepare print content and send it to the Printing Root. /// </summary> private void PreparePrintContent() { // Create and populate print page. var userPrintPage = Activator.CreateInstance(_printPageType) as Page; if (userPrintPage == null) { OnStatusChanged("Configuration error: print page type is not a Page subclass", EventLevel.Error); return; } // Apply DataContext. userPrintPage.DataContext = DataContext; // Create print template page and fill invisible textblock with empty paragraph. // This will push all 'real' content into the overflow. _firstPrintPage = new PrintPage(); _firstPrintPage.AddContent(new Paragraph()); // Flatten content from user print page to a list of paragraphs, and move these to the print template. var userPrintPageContent = userPrintPage.Content as RichTextBlock; if (userPrintPageContent == null) { OnStatusChanged("Configuration error: print page's main panel is not a RichTextBlock.", EventLevel.Error); return; } while (userPrintPageContent.Blocks.Count > 0) { var paragraph = userPrintPageContent.Blocks.First() as Paragraph; userPrintPageContent.Blocks.Remove(paragraph); var container = paragraph.Inlines[0] as InlineUIContainer; if (container != null) { var itemsControl = container.Child as ItemsControl; if (itemsControl?.Items != null) { // Render the paragraph (only to read the ItemsSource). Render(paragraph); // Transform each item to a paragraph, render separately, and add to the page. foreach (var item in itemsControl.Items) { var itemParagraph = new Paragraph(); var inlineContainer = new InlineUIContainer(); var element = (itemsControl.ContainerFromItem(item) as ContentPresenter).ContentTemplate.LoadContent() as UIElement; var frameworkElement = element as FrameworkElement; frameworkElement.DataContext = item; inlineContainer.Child = element; itemParagraph.Inlines.Add(inlineContainer); itemParagraph.LineHeight = Render(itemParagraph); _firstPrintPage.AddContent(itemParagraph); } } else { // Place the paragraph in a new textblock, and measure it. var actualHeight = Render(paragraph); // Apply line height to trigger overflow. paragraph.LineHeight = actualHeight; _firstPrintPage.AddContent(paragraph); } } else { _firstPrintPage.AddContent(paragraph); } } OnStatusChanged("Prepared " + _firstPrintPage.TextContent.Blocks.Count + " paragraphs."); // Send it to the printing root. PrintingRoot.Children.Clear(); PrintingRoot.Children.Add(_firstPrintPage); }
/// <summary> /// Applies height and width of the printer page. /// </summary> private void ApplyPrintPageDescription(PrintPageDescription printPageDescription, PrintPage printPage) { // Set paper size printPage.Width = printPageDescription.PageSize.Width; printPage.Height = printPageDescription.PageSize.Height; // Get the margins size // If the ImageableRect is smaller than the app provided margins use the ImageableRect. var marginWidth = Math.Max( printPageDescription.PageSize.Width - printPageDescription.ImageableRect.Width, printPageDescription.PageSize.Width * _horizontalPrintMargin * 2); var marginHeight = Math.Max( printPageDescription.PageSize.Height - printPageDescription.ImageableRect.Height, printPageDescription.PageSize.Height * _verticalPrintMargin * 2); // Set-up the printable area on the paper. printPage.PrintableArea.Width = printPage.Width - marginWidth; printPage.PrintableArea.Height = printPage.Height - marginHeight; OnStatusChanged("Printable area: width = " + printPage.PrintableArea.Width + ", height = " + printPage.PrintableArea.Height); // Add the page to the printing root which is part of the visual tree. // Force it to go through layout so that the overflow correctly distribute the content inside them. PrintingRoot.Children.Add(printPage); PrintingRoot.InvalidateMeasure(); PrintingRoot.UpdateLayout(); }