6

テキストの行が追加の行に折り返されている場合、文字列内の改行されたポイントをプログラムで特定するにはどうすればよいですか。

例: 入力文字列 = "これは折り返されたテキスト行のテストです".

      Based on the width of the richTextBox it could display:


            This is a test of a wrapped line of
            text.

私が決定する必要があるのは、ラップされた単語の行のオフセットです。上記の場合、単語「テキスト」。

richTextBox から Xaml を抽出すると、元のテキストがアンラップされます。

ありがとう、

ボブ・カーリンガー

4

3 に答える 3

2

私が見つけたトリックは、TextPointer クラスとその GetCharacterRec メソッドを使用しています。

RichTextBox は FlowDocument を保持します。フロー ドキュメント内のテキストは、Run オブジェクトに含まれています (少し単純化されていますが、機能します)。コードは、最初の Run の開始時に TextPointer を見つけます。次に、その最初の文字の外接する四角形を取得します。次に、コードは一度に 1 文字ずつ順方向に進み、新しい外接する四角形を取得し、新しい四角形の下部が元の四角形と異なるかどうかを確認します。底が異なる場合は、新しい行にいます。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>
于 2008-11-24T00:29:24.893 に答える
1

しかし、null をstartOfFirstLine.GetLineStartPosition(1)返します

于 2009-01-18T05:28:12.660 に答える
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;
}
于 2008-11-24T02:50:32.613 に答える