RichTextBox for WPF
レイアウト情報へのアクセス
RichTextBox for WPF の使い方 > レイアウト情報へのアクセス

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

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

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

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

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

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

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

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

コードのコピー
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
コードのコピー
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;
}

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