2008-11-20 12 views
6

Si une ligne de texte est encapsulée sur une ligne supplémentaire, comment puis-je déterminer par programme le point de la chaîne où elle a été rompue.WPF richTextBox question

Exemple: Input string = "Ceci est un test d'une ligne de texte encapsulée". Ce que j'ai besoin de déterminer est le décalage dans la ligne du (des) mot (s) enveloppé (s). Dans le cas ci-dessus le mot "texte".

Lorsque j'extrait le Xaml de la zone rich Text, le texte d'origine est déroulé.

Merci,

Bob Kerlinger

+0

Qu'est-ce que vous essayez d'utiliser ce décalage pour? –

+0

J'ai besoin d'extraire le texte composé tel qu'il est affiché pour que je puisse le réafficher exactement tel qu'il a été composé sur un autre support. En outre, dans certains cas, j'ai besoin de créer un retrait négatif que le fichier richTextBox ne prend pas en charge. Je dois aussi faire un autre formatage spécial. –

Répondre

2

L'astuce que j'ai trouvé utilise la classe TextPointer et sa méthode GetCharacterRec.

RichTextBox contient un FlowDocument. Le texte dans les documents de flux est contenu dans un objet Run (un peu simplifié, mais cela fonctionne). Le code trouve le TextPointer au début de la première exécution. Il obtient alors le rectangle englobant de ce premier caractère. Ensuite, le code avance d'un caractère à la fois, obtient un nouveau rectangle de délimitation et vérifie si le bas du nouveau rectangle est différent du rectangle d'origine. Si le fond est différent, nous sommes sur une nouvelle ligne. TextPointer peut alors obtenir le texte avant ou après la pause.

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

J'ai essayé cela au début mais le startOfNexLine a gardé la valeur null. Il semble trouver la position de départ de la prochaine exécution, mais il ne trouvera pas de pauses dans un objet Run. Je pourrais manquer quelque chose. –

+0

Je sais que je suis un peu en retard à la fête, mais avez-vous trouvé un moyen de contourner startOfNextLine retournant null? – JessMcintosh

1

Mais startOfFirstLine.GetLineStartPosition(1) retours null

Questions connexes