nam
nam

Reputation: 23749

WPF RichTexBox printing is creating unexpected line breaks

In RichTextBox of my WPF app, following print method is creating unexpected line breaks. Question: What I may be missing here, and how can we fix the issue?

For example, when I enter the following text in the RichTextBox (RTB), the RTB looks like as shown in image 1. But when I call the following two print methods the first one does not create the unexpected line breaks, but the second method does create unexpected line breaks:

MainWindow.xaml

<StackPanel>
    <RichTextBox Name="richTB" />

    <Button Click="PrintCommand1">Print RTB Content</Button>
    <Button Click="PrintCommand2">Print RTB Content</Button>
</StackPanel>

Method 1

private void PrintCommand1(Object sender, RoutedEventArgs args)
{
    PrintDialog pd = new PrintDialog();
    if ((pd.ShowDialog() == true))
    {
        pd.PrintVisual(richTB as Visual, "printing as visual");
    }
}

Method 2

private void PrintCommand2(Object sender, RoutedEventArgs args)
{
    PrintDialog pd = new PrintDialog();
    if ((pd.ShowDialog() == true))
    {
        pd.PrintDocument((((IDocumentPaginatorSource)richTB.Document).DocumentPaginator), "printing as paginator");
    }
}

The text I enter [Note: There is only one line break]

This is a test for testing purpose only. Another test: x6. Let us do some background and foreground colors.
This is a new line with formatting, as well.

Snapshot of the RichTexBox with above text

enter image description here

Snapshot of "Print to PDF" (on Windows 10) using Method 1 [Printed correctly with one real line break]

enter image description here

Snapshot of "Print to PDF" (on Windows 10) using Method 2 [Printed incorrectly with unexpected line breaks]

enter image description here

Upvotes: 1

Views: 133

Answers (1)

Victor
Victor

Reputation: 8915

Because of the DocumentPaginator class takes context of the FlowDocument and split in into multiple pages to get desired result some of FlowDocument parameters should be configured before printing:

private void PrintCommand2(Object sender, RoutedEventArgs args)
{
    var pd = new PrintDialog();
    if (pd.ShowDialog() == true)
    {
        FlowDocument doc = richTB.Document;

        // Save all settings that will be configured for printing.
        double pageHeight = doc.PageHeight;
        double pageWidth = doc.PageWidth;
        double columnGap = doc.ColumnGap;
        double columnWidth = doc.ColumnWidth;

        // Make the FlowDocument page match the printed page.
        doc.PageHeight = pd.PrintableAreaHeight;
        doc.PageWidth = pd.PrintableAreaWidth;                
        doc.ColumnGap = 5; 

        // Set the minimum desired width of the column in the System.Windows.Documents.FlowDocument.
        doc.ColumnWidth = doc.PageWidth - doc.ColumnGap - doc.PagePadding.Left - doc.PagePadding.Right;
        pd.PrintDocument(((IDocumentPaginatorSource)doc).DocumentPaginator, "A Flow Document");

        // Reapply the old settings.
        doc.PageHeight = pageHeight;
        doc.PageWidth = pageWidth;                
        doc.ColumnGap = columnGap;
        doc.ColumnWidth = columnWidth;
    }
}

With respect to Matthew MacDonald this way of the flow document content printing and more advanced techniques described in his book Pro WPF 4.5 in C# Windows Presentation Foundation in .NET 4.5 (Chapter 29).

Upvotes: 1

Related Questions