2008-11-20 133 views
6

如果将一行文本换行到另一行,我如何通过编程方式确定该字符串中断点的位置。WPF richTextBox问题

示例:输入字符串=“这是一个包装文本行的测试”。

 Based on the width of the richTextBox it could display: 


      This is a test of a wrapped line of 
      text. 

我需要确定的是在被包裹的单词的行中偏移。在上述情况下,单词“文字”。

当我从richTextBox中提取Xaml时,我得到原始文本解包。

感谢,

鲍勃Kerlinger

+0

什么是你想使用这个偏移? – 2008-11-20 22:38:16

+0

我需要在合成文本显示时提取出合成文本,以便我可以重新显示它,就像它在另一个介质上合成一样。另外,在某些情况下,我需要创建一个richTextBox不支持的悬挂缩进。我还必须做一些其他的特殊格式。 – 2008-11-21 16:42:51

回答

2

我找到诀窍使用TextPointer类及其GetCharacterRec方法。

RichTextBox包含一个FlowDocument。流文档中的文本包含在一个Run对象中(简化中的一点,但它有效)。代码在第一次运行开始时找到TextPointer。然后获取第一个字符的边界矩形。接下来,代码每次向前走一个字符,获取一个新的边界矩形,并检查新矩形的底部是否与原始矩形不同。如果底部不同,那么我们正在换一个新的线。 TextPointer可以在中断之前或之后获取文本。

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

startOfFirstLine.GetLineStartPosition(1)回报