3
votes

I haven't been able to do multipage printing with Richeditbox. I have Richeditbox in Xaml named Editor. I use custom GetText() function to get all content inside of Editor. I have been able to do printing with single page but don't have idea how i can make multiple pages.

I have tried to look Microsoft Documentation and this PrintHelper class. Still I am not sure how I should implement this to my project.

So main question is how should I do printing with multiple pages with richeditbox?

Below is my project printing code and yes i know that there is hard coded: printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final); But don't know how i should count those pages

 private PrintManager printMan;
 private PrintDocument printDoc;
 private IPrintDocumentSource printDocSource;

public MainPage()
{
    InitializeComponent();
    // Register for PrintTaskRequested event
    printMan = PrintManager.GetForCurrentView();
    printMan.PrintTaskRequested += PrintTaskRequested;

    // Build a PrintDocument and register for callbacks
    printDoc = new PrintDocument();
    printDocSource = printDoc.DocumentSource;
    printDoc.Paginate += Paginate;
    printDoc.GetPreviewPage += GetPreviewPage;
    printDoc.AddPages += AddPages;
}

private async void Print_Click(object sender, RoutedEventArgs e)
{
    if (PrintManager.IsSupported())
    {
        try
        {
            // Show print UI
            await PrintManager.ShowPrintUIAsync();
        }
        catch
        {
            // Printing cannot proceed at this time
            ContentDialog noPrintingDialog = new ContentDialog()
            {
                Title = "Printing error",
                Content = "\nSorry, printing can' t proceed at this time.",
                PrimaryButtonText = "OK"
            };
            await noPrintingDialog.ShowAsync();
        }
    }
    else
    {
        // Printing is not supported on this device
        ContentDialog noPrintingDialog = new ContentDialog()
        {
            Title = "Printing not supported",
            Content = "\nSorry, printing is not supported on this device.",
            PrimaryButtonText = "OK"
        };
        await noPrintingDialog.ShowAsync();
    }

}

private void PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
    // Create the PrintTask.
    // Defines the title and delegate for PrintTaskSourceRequested
    var printTask = args.Request.CreatePrintTask("Print", PrintTaskSourceRequrested);

    // Handle PrintTask.Completed to catch failed print jobs
    printTask.Completed += PrintTaskCompleted;
}

private void PrintTaskSourceRequrested(PrintTaskSourceRequestedArgs args)
{
    // Set the document source.
    args.SetSource(printDocSource);
}

private void Paginate(object sender, PaginateEventArgs e)
{
    printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final);
}

private void GetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
    string text = GetText(); ;
    RichEditBox richTextBlock = new RichEditBox();
    richTextBlock.Document.SetText(TextSetOptions.FormatRtf, text);
    richTextBlock.Background = new SolidColorBrush(Windows.UI.Colors.White);
    printDoc.SetPreviewPage(e.PageNumber, richTextBlock);
}


private void AddPages(object sender, AddPagesEventArgs e)
{
    string text = GetText(); ;
    RichEditBox richTextBlock = new RichEditBox();
    richTextBlock.Document.SetText(TextSetOptions.FormatRtf, text);
    richTextBlock.Background = new SolidColorBrush(Windows.UI.Colors.White);
    richTextBlock.Padding = new Thickness(20,20,20,20);
    printDoc.AddPage(richTextBlock);

    // Indicate that all of the print pages have been provided
    printDoc.AddPagesComplete();
}

private async void PrintTaskCompleted(PrintTask sender, PrintTaskCompletedEventArgs args)
{
    // Notify the user when the print operation fails.
    if (args.Completion == PrintTaskCompletion.Failed)
    {
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            ContentDialog noPrintingDialog = new ContentDialog()
            {
                Title = "Printing error",
                Content = "\nSorry, failed to print.",
                PrimaryButtonText = "OK"
            };
            await noPrintingDialog.ShowAsync();
        });
    }
}
1

1 Answers

5
votes

RichTextBlock has OverflowContentTarget property. You should specify RichTextBlockOverflow control there. RichTextBlockOverflow control may also have OverflowContentTarget. So you add additinal page and look if it has overflow content or not. Content which didn't suit the page flows to the next overflow control and so on. So you render pages one by one until there is nothing in overflow and at that moment you know page count.

Just exactly what I said but in their official docs:

lastRTBOOnPage = AddOnePrintPreviewPage(null, pageDescription);

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

MS docs skip important points and hard to understand. The best documentation on printing is this blog by Diederic Krols. There is also nice article written by him how to print from ItemsControl. (but it's more advanced) It's for windows 8, but API didn't change since that time.

enter image description here