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);
    }