2008-11-20 4 views
6

Wenn eine Textzeile in eine zusätzliche Zeile eingeschlossen wird, wie programmiere ich programmatisch den Punkt in der Zeichenfolge, wo es unterbrochen wurde.WPF richTextBox-Frage

Beispiel: Eingabezeichenfolge = "Dies ist ein Test einer umbrochenen Textzeile".

 Based on the width of the richTextBox it could display: 


      This is a test of a wrapped line of 
      text. 

Was ich feststellen muss, ist Offset in der Zeile der Wörter, die verpackt wurden. Im obigen Fall das Wort "Text".

Wenn ich den Xaml aus der RichTextBox extrahiere, bekomme ich den ursprünglichen Text ausgepackt.

Danke,

Bob Kerlinger

+0

Was Sie versuchen, diese für den Offset zu benutzen? –

+0

Ich muss den zusammengesetzten Text so extrahieren, wie er angezeigt wird, damit ich ihn genau so wieder anzeigen kann, wie er auf einem anderen Medium erstellt wurde. In einigen Fällen muss ich einen hängenden Einzug erstellen, den die richTextBox nicht unterstützt. Ich muss auch eine andere spezielle Formatierung machen. –

Antwort

2

Der Trick, den ich verwendet Methode, um die Textpointer-Klasse und ihre GetCharacterRec gefunden.

RichTextBox enthält ein FlowDocument. Text in Flussdokumenten ist in einem Run-Objekt enthalten (ein bisschen Vereinfachung, aber es funktioniert). Der Code findet den TextPointer zu Beginn des ersten Laufs. Es erhält dann das umschließende Rechteck dieses ersten Zeichens. Als nächstes geht der Code ein Zeichen nach dem anderen vor, erhält ein neues Begrenzungsrechteck und prüft, ob sich das Ende des neuen Rechtecks ​​vom ursprünglichen Rechteck unterscheidet. Wenn der Boden anders ist, dann sind wir auf einer neuen Linie. TextPointer kann dann den Text entweder vor oder nach der Pause erhalten.

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> 
1

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; 
} 
+0

Ich habe das zuerst versucht, aber die startOfNexLine hat immer null zurückgegeben. Es scheint die Startposition des nächsten Laufs zu finden, aber es werden keine Unterbrechungen innerhalb eines Run-Objekts gefunden. Ich könnte etwas verpassen. –

+0

Ich weiß, dass ich ein bisschen spät auf die Party bin, aber hast du einen Weg gefunden, um herumzukommen startOfNextLine Null zurückgeben? – JessMcintosh

1

Aber startOfFirstLine.GetLineStartPosition(1) kehrt null