WPF question richTextBox

If a line of text is wrapped in an additional line, how can I programmatically determine the point in the line where it was broken.

Example: Input line = "This is a check for a wrapped text line."

Based on the width of the richTextBox it could display: This is a test of a wrapped line of text. 

What I need to determine is offset in the line of the word (s) that was wrapped. In the above case, the word "text".

When I retrieve Xaml from a richTextBox, I get the source code expanded.

Thanks,

Bob curlinger

+6
c # wpf richtextbox
source share
3 answers

The trick found uses the TextPointer class and its GetCharacterRec method.

RichTextBox contains a FlowDocument. The text in the flow documents is contained in the Run object (simplification bit, but it works). The code finds TextPointer at the start of the first run. Then it gets the bounding box of this first character. The code then moves forward one character at a time, receives a new bounding box, and checks to see if the bottom of the new box is different from the original box. If the bottom is different, we are on a new line. TextPointer can receive text before or after a break.

 public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void inspect(object sender, RoutedEventArgs e) { TextPointer pointer = FindRun(inBox.Document); string textAfterBreak = FindBreak(pointer); outBox.Text = textAfterBreak; } private string FindBreak(TextPointer pointer) { Rect rectAtStart = pointer.GetCharacterRect(LogicalDirection.Forward); pointer = pointer.GetNextInsertionPosition(LogicalDirection.Forward); Rect currentRect = pointer.GetCharacterRect(LogicalDirection.Forward); while (currentRect.Bottom == rectAtStart.Bottom) { pointer = pointer.GetNextInsertionPosition(LogicalDirection.Forward); currentRect = pointer.GetCharacterRect(LogicalDirection.Forward); } string textBeforeBreak = pointer.GetTextInRun(LogicalDirection.Backward); string textAfterBreak = pointer.GetTextInRun(LogicalDirection.Forward); return textAfterBreak; } private TextPointer FindRun(FlowDocument document) { TextPointer position = document.ContentStart; while (position != null) { if (position.Parent is Run) break; position = position.GetNextContextPosition(LogicalDirection.Forward); } return position; } } <Window x:Class="LineBreaker.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <RichTextBox Grid.Row="0" Name="inBox"> </RichTextBox> <Button Grid.Row="1" Click="inspect">Find Break</Button> <TextBox Name="outBox" Grid.Row="2"/> </Grid> </Window> 
+2
source share

http://msdn.microsoft.com/en-us/library/system.windows.documents.textpointer.getlinestartposition.aspx

 TextPointer startOfFirstLine = richTextBox.Document.ContentStart; TextPointer startOfNextLine = startOfFirstLine.GetLineStartPosition(1); if(startOfNextLine != null) { // At this point what you do with the TextPointer depends on what you define as the position of text. // If you want to find out how many characters are on the first line ... int firstLineCharacterCount = new TextRange(startOfFirstLine, startOfNextLine).Text.Length; } 
+1
source share

But startOfFirstLine.GetLineStartPosition(1) returns null

+1
source share

All Articles