3

I'm attempting to align a flow document to the left with no padding, so that it matches exactly what you see in a TextBlock. I've recreated a simple example of what I'm basically trying to achieve. Here's what I have so far:

<Grid>
    <TextBlock Foreground="Red" Height="Auto" TextWrapping="Wrap"
            Margin="0" Padding="0" FontSize="50" FontFamily="Arial"
            Text="Some text."/>
    <RichTextBox BorderThickness="0" Background="Transparent" BorderBrush="Transparent" IsInactiveSelectionHighlightEnabled="False" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled"
            Height="Auto"
            Margin="0" Padding="0" FontSize="50" FontFamily="Arial" >
        <FlowDocument PagePadding="0" LineStackingStrategy="BlockLineHeight">
            <Paragraph Margin="0" Padding="0" TextIndent="0">Some text.</Paragraph>
        </FlowDocument>
    </RichTextBox>
</Grid>

Here's the result:

enter image description here

As you can see, the red is the TextBlock version and the black is the RichTextBox/FlowDocument version. The FlowDocument text is offset by about 5 pixels to the right. I've tried to remove all padding that I am aware of, but I still can't get rid of that offset. Any help is appreciated.

NOTE: This question is found as duplicate of WPF: How to make RichTextBox look like TextBlock?

Jackdaw
  • 7,626
  • 5
  • 15
  • 33

1 Answers1

3

This offset is related to the caret implementation in the RichTextBox control.

Look at .Net 4.8 source, in the RichTextBox.cs file:

// Allocates the initial render scope for this control.
internal override FrameworkElement CreateRenderScope()
{
    FlowDocumentView renderScope = new FlowDocumentView();
    renderScope.Document = this.Document;

    // Set a margin so that the BiDi Or Italic caret has room to render at the edges of content.
    // Otherwise, anti-aliasing or italic causes the caret to be partially clipped.
    renderScope.Document.PagePadding = new Thickness(CaretElement.CaretPaddingWidth, 0, CaretElement.CaretPaddingWidth, 0);

    // We want current style to ignore all properties from theme style for renderScope.
    renderScope.OverridesDefaultStyle = true;

    return renderScope;
}

And the CaretElement.CaretPaddingWidth definition in the CaretElement.cs file:

// Caret padding width to ensure the visible caret for Bidi and Italic.
// Control(TextBox/RichTextBox) must have the enough padding to display
// BiDi and Italic caret indicator.
internal const double CaretPaddingWidth = 5.0;

Therefore, the only option that you can check is set the RichTextBox margin to Margin="-5,0,0,0".

Jackdaw
  • 7,626
  • 5
  • 15
  • 33
  • This answer explains the problem precisely, so I'll mark it as answered. However, I figured out that this question was basically a duplicate of: https://stackoverflow.com/questions/5820578/wpf-how-to-make-richtextbox-look-like-textblock and used the answer from there to make my fix. – Dan Goodman Mar 12 '21 at 06:28
  • @Dan Goodman: Thank you, very kind. I glad you found an answer. According to the SO rules it is better to delete the duplicate question. If you can unmark my answer as the solution I will able to delete my answer... – Jackdaw Mar 12 '21 at 10:38
  • Almost a year later, I have discovered that the other fix causes a memory leak, at least in my situation, so I'm glad that this still exists as a potential answer. Thank you. – Dan Goodman Jan 25 '22 at 15:58
  • I found that setting Padding="-5 0 -5 0" works better than Margin with Multiline and Horizontal Center Alignment. – Dan Goodman Feb 16 '22 at 11:29
  • @DanGoodman: Have you tried using an Italic font and also increasing the font size significantly? Because with using the Padding, the cursor and text can go beyond the document and this can lead to a drawing outside the document. Therefore I would prefer to use the margin in this case. – Jackdaw Feb 16 '22 at 20:27