RichTextBox for UWP
レイアウト情報へのアクセス
RichTextBox の使い方 > 主要な概念と機能 > レイアウト情報へのアクセス

C1RichTextBox によって C1Document レイアウトを作成すると、C1TextElementView オブジェクトで構成されるツリーが並行して作成されます。C1Document ツリー内の各 C1TextElement には、レイアウトと描画の役割を担う C1TextElementView が1つ以上含まれます。

この C1Document ツリーを例にします。

対応するビューツリーは次のようになります。

各 C1TextElementView は、対応する C1TextElement の基本レイアウト情報を提供します。

C1TextElementView.Origin: ドキュメント座標によるビューの原点です。

C1TextElementView.DesiredSize: 最後に測定されたときからのビューに必要なサイズです。

レイアウトと描画を処理するために、外側の C1TextElement を複数の C1TextElementView で構成することもできます。その場合、C1TextElementView.Content プロパティには、構成内の最も内側の C1TextElementView が含まれます。コンテンツビューの子は、関連付けられている C1TextElement の C1TextElementView.Children コレクションに対応します。

ビューの構成は、C1TextElementView.Content ビューのマージン、パディング、および境界を処理するために C1BoxView で使用されます。つまり、各 C1BoxView の原点はマージン、パディング、および境界ボックスの外側で、C1TextElementView.Content の原点は内側です。

C1FlowView は、いくつかの行としてフローするボックスやテキストを表します。各行は、C1Line オブジェクトによって表されます。C1Line オブジェクトには、単一行のテキストだけでなく、段落全体が含まれる場合もあります。各 C1FlowView には C1Line のリストが含まれ、これらの行は常に垂直方向に積み重ねられます。各 C1Line はいくつかの C1LineFragment で構成され、これらの行フラグメントは水平方向に積み重ねられます。C1LineFragment には子要素の参照が含まれ、その原点はフラグメントの位置に一致します。

たとえば、次のコードは C1RichTextBox 内の行数をカウントします。

Visual Basic コードの書き方

Visual Basic
コードのコピー
Private Function CountLines(rtb As C1RichTextBox) As Integer
    Dim root = rtb.ViewManager.GetView(rtb.Document)
    Return CountLines(root)
End Function

Private Function CountLines(view As C1TextElementView) As Integer
    Dim count As Integer = 0
    Dim flow = TryCast(view, C1FlowView)
    If flow IsNot Nothing Then
        For Each line As var In flow.Lines
            If TypeOf line.Fragments.First().Element Is C1Inline Then
                count += 1
            End If
        Next
    End If
    For Each child As var In view.Children
        count += CountLines(child)
    Next
    Return count
End Function

C# コードの書き方

C#
コードのコピー
int CountLines(C1RichTextBox rtb)
{
    var root = rtb.ViewManager.GetView(rtb.Document);
    return CountLines(root);
}

int CountLines(C1TextElementView view)
{
    int count = 0;
    var flow = view as C1FlowView;
    if (flow != null)
    {
        foreach (var line in flow.Lines)
        {
            if (line.Fragments.First().Element is C1Inline)
            {
                ++count;
            }
        }
    }
    foreach (var child in view.Children)
    {
        count += CountLines(child);
    }
    return count;
}

まず、ルートビューを取得します。これはルート要素に関連付けられているビューと同じなので、C1RichTextViewManager.GetView を使用して rtb.Document のビューを取得します。次に、ビューツリーを走査して、各 C1FlowView で見つかった行数がカウントされます。C1Inline 要素の行数だけをカウントすることに注意してください。そうしないと、段落などのコンテナブロックもカウントしてしまいます。