private static void GetPrintPreviewPage(object sender, GetPreviewPageEventArgs e) { Interlocked.Exchange(ref currentPreviewPage, e.PageNumber - 1); PageLoadState pageLoadState = printPreviewPages[e.PageNumber - 1]; if (!pageLoadState.Ready) { // Notify the user that some content is not available yet // Apps may also opt to don't show preview untill everything is complete and just use await IsReadyAsync //rootPage.NotifyUser("Image loading not complete, previewing only text", NotifyType.ErrorMessage); } // Set the preview even if images failed to load properly printDocument.SetPreviewPage(e.PageNumber, pageLoadState.Page); }
private static RichTextBlockOverflow AddOnePrintPreviewPage(RichTextBlockOverflow lastRTBOAdded, PrintPageDescription printPageDescription) { // Create a cavase which represents the page Canvas page = new Canvas(); page.Width = printPageDescription.PageSize.Width; page.Height = printPageDescription.PageSize.Height; PageLoadState pageState = new PageLoadState(page, printPreviewPages.Count); pageState.ReadyAction = async(pageNumber, currentPage) => { // Ignore if this is not the current page if (Interlocked.CompareExchange(ref currentPreviewPage, currentPreviewPage, pageNumber) == pageNumber) { await Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { //await new Windows.UI.Popups.MessageDialog("Content loaded").ShowAsync(); printDocument.SetPreviewPage(pageNumber + 1, currentPage); }); } }; // Create a grid which contains the actual content to be printed Grid content = new Grid(); // 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 content size based on the given margins content.Width = printPageDescription.PageSize.Width - marginWidth; content.Height = printPageDescription.PageSize.Height - marginHeight; // Set content margins content.SetValue(Canvas.LeftProperty, marginWidth / 2); content.SetValue(Canvas.TopProperty, marginHeight / 2); // Add the RowDefinitions to the Grid which is a content to be printed RowDefinition rowDef = new RowDefinition(); rowDef.Height = new GridLength(2.5, GridUnitType.Star); content.RowDefinitions.Add(rowDef); rowDef = new RowDefinition(); rowDef.Height = new GridLength(3.5, GridUnitType.Star); content.RowDefinitions.Add(rowDef); rowDef = new RowDefinition(); rowDef.Height = new GridLength(1.5, GridUnitType.Star); content.RowDefinitions.Add(rowDef); // If lastRTBOAdded is null then we know we are creating the first page. bool isFirstPage = lastRTBOAdded == null; FrameworkElement previousLTCOnPage = null; RichTextBlockOverflow rtbo = new RichTextBlockOverflow(); // Create the linked containers and and add them to the content grid if (isFirstPage) { // The first linked container in a chain of linked containers is is always a RichTextBlock RichTextBlock rtbl = new RichTextBlock(); rtbl.SetValue(Grid.RowProperty, 0); rtbl = AddContentToRTBl(rtbl); int a = rtbl.Blocks.Count(); rtbl.Foreground = new SolidColorBrush(Windows.UI.Colors.Black); content.Children.Add(rtbl); // Save the RichTextBlock as the last linked container added to this page previousLTCOnPage = rtbl; } else { // This is not the first page so the first element on this page has to be a // RichTextBoxOverflow that links to the last RichTextBlockOverflow added to // the previous page. rtbo = new RichTextBlockOverflow(); rtbo.SetValue(Grid.RowProperty, 0); content.Children.Add(rtbo); // Keep text flowing from the previous page to this page by setting the linked text container just // created (rtbo) as the OverflowContentTarget for the last linked text container from the previous page lastRTBOAdded.OverflowContentTarget = rtbo; // Save the RichTextBlockOverflow as the last linked container added to this page previousLTCOnPage = rtbo; } if (ShowText) { // Create the next linked text container for on this page. rtbo = new RichTextBlockOverflow(); rtbo.SetValue(Grid.RowProperty, 1); // Add the RichTextBlockOverflow to the content to be printed. content.Children.Add(rtbo); // Add the new RichTextBlockOverflow to the chain of linked text containers. To do this we much check // to see if the previous container is a RichTextBlock or RichTextBlockOverflow. if (previousLTCOnPage is RichTextBlock) { ((RichTextBlock)previousLTCOnPage).OverflowContentTarget = rtbo; } else { ((RichTextBlockOverflow)previousLTCOnPage).OverflowContentTarget = rtbo; } // Save the last linked text container added to the chain previousLTCOnPage = rtbo; // Create the next linked text container for on this page. rtbo = new RichTextBlockOverflow(); rtbo.SetValue(Grid.RowProperty, 2); content.Children.Add(rtbo); // Add the new RichTextBlockOverflow to the chain of linked text containers. We don't have to check // the type of the previous linked container this time because we know it's a RichTextBlockOverflow element ((RichTextBlockOverflow)previousLTCOnPage).OverflowContentTarget = rtbo; } // We are done creating the content for this page. Add it to the Canvas which represents the page page.Children.Add(content); // Add the newley 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(); // Add the newley created page to the list of pages printPreviewPages.Add(pageState); // Return the last linked container added to the page return(rtbo); }