I have a FlowDocument like this:
<FlowDocument>
<Paragraph>
<Span>
<Run Background="#FFFFDAB9">{</Run>
<Run Background="#FFB0E0E6">a</Run>
<Run FontWeight="Bold" Background="#FFFFDAB9">||</Run>
<Run Background="#FFB0E0E6">b</Run>
<Run Background="#FFFFDAB9">}</Run>
</Span>
</Paragraph>
</FlowDocument>
When I set the RichTextBox.Caret to the second Run.ContentStart (before the "a" char), everything works fine. But when I replace the char "a" with a " " (simple space char), then I'm no longer able to place the Caret to the ContentStart of the Run.
<FlowDocument>
<Paragraph>
<Span>
<Run Background="#FFFFDAB9">{</Run>
<Run Background="#FFB0E0E6" xml:space="preserve"> </Run>
<Run FontWeight="Bold" Background="#FFFFDAB9">||</Run>
<Run Background="#FFB0E0E6">b</Run>
<Run Background="#FFFFDAB9">}</Run>
</Span>
</Paragraph>
</FlowDocument>
The Caret will remain behind the "}" (the first Run.ContentEnd).
I made a simple "debug" function to show and set the RichTextBox.Caret. To test this, you have to replace the linebreaks, so you have a single-line XAML. I just formated the XAML for better readability.
Private Sub SetRichTextBoxCarret(thisRTB As RichTextBox, thisTP As TextPointer, Optional additionalOffset As Int32 = 0)
Dim myDirection = If(CBool(thisRTB.CaretPosition.LogicalDirection), LogicalDirection.Backward, LogicalDirection.Forward)
Debug.WriteLine("")
Debug.WriteLine(String.Format("SetRichTextBoxCarret - TextPointerOffset: {0}", thisRTB.Document.ContentStart.GetOffsetToPosition(thisTP)))
Debug.WriteLine(String.Format("SetRichTextBoxCarret - TextPointerText: {0}", thisTP.GetTextInRun(myDirection)))
Debug.WriteLine(String.Format("SetRichTextBoxCarret - CaretOffset Before: {0}", thisRTB.Document.ContentStart.GetOffsetToPosition(thisRTB.CaretPosition)))
Dim myDestinationPosition = thisTP.GetPositionAtOffset(additionalOffset, myDirection)
thisRTB.CaretPosition = myDestinationPosition
Debug.WriteLine(String.Format("SetRichTextBoxCarret - CaretOffset After: {0}", thisRTB.Document.ContentStart.GetOffsetToPosition(thisRTB.CaretPosition)))
End Sub
I call this this routine in this way (for example)
Private Sub Set1_Click(sender As Object, e As RoutedEventArgs)
Dim myRTB = Me.rtbSearchCriteria1
Dim myParagraph = DirectCast(myRTB.Document.Blocks(0), Paragraph)
Dim mySpan = DirectCast(myParagraph.Inlines(0), Span)
Dim myRun = DirectCast(mySpan.Inlines(1), Run)
myRTB.Focus()
SetRichTextBoxCarret(myRTB, myRun.ContentStart)
End Sub
which shows the following in the output window:
SetRichTextBoxCarret - TextPointerOffset: 6
SetRichTextBoxCarret - TextPointerText: a
SetRichTextBoxCarret - CaretOffset Before: 3
SetRichTextBoxCarret - CaretOffset After: 6
but, when I have the 2nd Flowdocument (with a space char instead of the "a" char) I'll get this
SetRichTextBoxCarret - TextPointerOffset: 6
SetRichTextBoxCarret - TextPointerText:
SetRichTextBoxCarret - CaretOffset Before: 3
SetRichTextBoxCarret - CaretOffset After: 4
the caret is 2 symbols away from "myRun.ContentStart". and there is no way to reach this position.
I have read a lot about the TextPointers and the documentation says "Each 16-bit Unicode character inside of a text Run element". As far as I remember, a space char is a Unicode char and it is obviously inside of an run element.
Am I missing something here or is this simply a bug? Is there a way to disable a "caret-position-repositioning" in the RichTextBox?
This behaves the same way when I call "RichTextBox.Selection.Select(myDestinationPosition, myDestinationPosition". Also it is not possible with .NextInsertPosition or .NextContextPosition. The caret will then overjump the Run.ContentStart.
And yes - I try to make some simple Syntax-Highlighting
I made a simple DemoApp here: DemoApp