2008-11-20 175 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)回報