RichTextBox for WPF
ドキュメントとレポートの作成
C1Document オブジェクトの使い方 > ドキュメントとレポートの作成

C1Document を作成するプロセスの例を示すために、簡単なアセンブリドキュメントユーティリティを実装するために必要な手順について説明します。

まず、新しいプロジェクトを作成し、C1.WPF.4 または C1.Silverlight.4 アセンブリと C1.WPF.RichTextBox.4 または C1.Silverlight.RichTextBox.5 アセンブリへの参照を追加します。次に、ページのコンストラクタを次のように編集します。

コードのコピー
Imports C1.WPF
Imports C1.WPF.RichTextBox
Imports C1.WPF.RichTextBox.Documents
Public Partial Class MainPage
   Inherits UserControl
  ' C1Document ドキュメントを表示する C1RichTextBox
   Private _rtb As C1RichTextBox
   Public Sub New()
       ' デフォルトの初期化
       InitializeComponent()
      ' C1RichTextBox を作成してページに追加します
       _rtb = New C1RichTextBox()
       LayoutRoot.Children.Add(_rtb)
       ' ドキュメントを作成して C1RichTextBox に表示します
       _rtb.Document = DocumentAssembly(GetType(C1RichTextBox).Assembly)
       _rtb.IsReadOnly = True
   End Sub
End Class
コードのコピー
using C1.WPF;
using C1.WPF.RichTextBox;
using C1.WPF.RichTextBox.Documents;
public partial class MainPage : UserControl
{
  // C1Document ドキュメントを表示する C1RichTextBox
  C1RichTextBox _rtb;
  public MainPage()
   {
    // デフォルトの初期化
    InitializeComponent();
    // C1RichTextBox を作成してページに追加します
    _rtb = new C1RichTextBox();
    LayoutRoot.Children.Add(_rtb);
    // ドキュメントを作成して C1RichTextBox に表示します
    _rtb.Document = DocumentAssembly(typeof(C1RichTextBox).Assembly);
    _rtb.IsReadOnly = true;
   }
}

このコードは、C1RichTextBox を作成し、その Document プロパティに DocumentAssembly メソッドの呼び出しの結果を割り当てます。次に、ユーザーがレポートを変更できないようにコントロールを読み取り専用にします。

DocumentAssembly メソッドは、Assembly を引数として受け取り、アセンブリドキュメントを含む C1Document を構築します。実装は次のとおりです。

コードのコピー
Private Function DocumentAssembly(asm As Assembly) As C1Document
   ' ドキュメントを作成します
   Dim doc As New C1Document()
   doc.FontFamily = New FontFamily("Tahoma")
   ' アセンブリ
   doc.Blocks.Add(New Heading1("Assembly" & vbCr & vbLf + asm.FullName.Split(","C)(0)))
   ' タイプ
   For Each t As Type In asm.GetTypes()
       DocumentType(doc, t)
   Next
   ' Done
   Return doc
End Function
コードのコピー
C1Document DocumentAssembly(Assembly asm)
{
  // ドキュメントを作成します
  C1Document doc = new C1Document();
  doc.FontFamily = new FontFamily("Tahoma");
  // アセンブリ
  doc.Blocks.Add(new Heading1("Assembly\r\n" + asm.FullName.Split(',')[0]));
  // タイプ
  foreach (Type t in asm.GetTypes())
   DocumentType(doc, t);
  // Done
  return doc;
}

このメソッドは、最初に新しい C1Document オブジェクトを作成し、その FontFamily プロパティを設定します。これは、ドキュメントに追加されるすべてのテキスト要素のデフォルト値になります。

次に、このメソッドは、アセンブリ名を含む Heading1 段落を新しいドキュメントの Blocks コレクションに追加します。ブロックは、ドキュメントに縦方向に並べられる段落、リスト項目などの要素から成ります。ブロックは、HTML の "div" 要素に似ています。ドキュメント要素には、代わりに Inlines コレクションが含まれる場合もあります。これらのコレクションには、HTML の "span" 要素のように、横方向に並べられる要素が含まれます。

Heading1 クラスは C1Paragraph を継承し、書式設定を追加します。ここでは、通常の段落と見出し1~4に対応するこのようなクラスをいくつかプロジェクトに追加します。

Normal 段落は、コンストラクタでコンテンツ文字列を受け取る C1Paragraph です。

コードのコピー
Class Normal
   Inherits C1Paragraph
   Public Sub New(text As String)
       Me.Inlines.Add(New C1Run() With { _
           Key .Text = text _
      })
       Me.Padding = New Thickness(30, 0, 0, 0)
       Me.Margin = New Thickness(0)
   End Sub
End Class
コードのコピー
class Normal : C1Paragraph
{
  public Normal(string text)
   {
    this.Inlines.Add(new C1Run() { Text = text });
    this.Padding = new Thickness(30, 0, 0, 0);
    this.Margin = new Thickness(0);
   }
}

Heading 段落は、Normal を拡張してテキストを太字にします。

コードのコピー
Class Heading
   Inherits Normal
   Public Sub New(text As String)
       MyBase.New(text)
       Me.FontWeight = FontWeights.Bold
   End Sub
End Class
コードのコピー
class Heading : Normal
{
  public Heading(string text) : base(text)
   {
    this.FontWeight = FontWeights.Bold;
   }
}

Heading1 から Heading4 は、Heading を拡張してフォントサイズ、パディング、境界、および色を指定します。

コードのコピー
Class Heading1
   Inherits Heading
   Public Sub New(text As String)
       MyBase.New(text)
       Me.Background = New SolidColorBrush(Colors.Yellow)
       Me.FontSize = 24
       Me.Padding = New Thickness(0, 10, 0, 10)
       Me.BorderBrush = New SolidColorBrush(Colors.Black)
       Me.BorderThickness = New Thickness(3, 1, 1, 0)
   End Sub
End Class
Class Heading2
   Inherits Heading
   Public Sub New(text As String)
       MyBase.New(text)
       Me.FontSize = 18
       Me.FontStyle = FontStyles.Italic
       Me.Background = New SolidColorBrush(Colors.Yellow)
       Me.Padding = New Thickness(10, 5, 0, 5)
       Me.BorderBrush = New SolidColorBrush(Colors.Black)
       Me.BorderThickness = New Thickness(3, 1, 1, 1)
   End Sub
End Class
Class Heading3
   Inherits Heading
   Public Sub New(text As String)
       MyBase.New(text)
       Me.FontSize = 14
       Me.Background = New SolidColorBrush(Colors.LightGray)
       Me.Padding = New Thickness(20, 3, 0, 0)
   End Sub
End Class
Class Heading4
   Inherits Heading
   Public Sub New(text As String)
       MyBase.New(text)
       Me.FontSize = 14
       Me.Padding = New Thickness(30, 0, 0, 0)
   End Sub
End Class
コードのコピー
class Heading1 : Heading
{
  public Heading1(string text) : base(text)
   {
    this.Background = new SolidColorBrush(Colors.Yellow);
    this.FontSize = 24;
    this.Padding = new Thickness(0, 10, 0, 10);
    this.BorderBrush = new SolidColorBrush(Colors.Black);
    this.BorderThickness = new Thickness(3, 1, 1, 0);
   }
}
class Heading2 : Heading
{
  public Heading2(string text): base(text)
   {
    this.FontSize = 18;
    this.FontStyle = FontStyles.Italic;
    this.Background = new SolidColorBrush(Colors.Yellow);
    this.Padding = new Thickness(10, 5, 0, 5);
    this.BorderBrush = new SolidColorBrush(Colors.Black);
    this.BorderThickness = new Thickness(3, 1, 1, 1);
   }
}
class Heading3 : Heading
{
  public Heading3(string text) : base(text)
   {
    this.FontSize = 14;
    this.Background = new SolidColorBrush(Colors.LightGray);
    this.Padding = new Thickness(20, 3, 0, 0);
   }
}
class Heading4 : Heading
{
  public Heading4(string text): base(text)
   {
    this.FontSize = 14;
    this.Padding = new Thickness(30, 0, 0, 0);
   }
}

これでドキュメント内の各段落タイプに対応するクラスを設定したので、次にコンテンツを追加します。最初のコードブロックで DocumentType メソッドを使用したことを思い出してください。次にそのメソッドの実装を示します。

コードのコピー
Private Sub DocumentType(doc As C1Document, t As Type)
 ' 非パブリック/ジェネリックはスキップします
   If Not t.IsPublic OrElse t.ContainsGenericParameters Then
      Return
   End If
  ' タイプ
   doc.Blocks.Add(New Heading2("Class " & Convert.ToString(t.Name)))
  ' プロパティ
   doc.Blocks.Add(New Heading3("Properties"))
   For Each pi As PropertyInfo In t.GetProperties()
       If pi.DeclaringType = t Then
           DocumentProperty(doc, pi)
       End If
   Next
' メソッド
       doc.Blocks.Add(New Heading3("Methods"))
   For Each mi As MethodInfo In t.GetMethods()
       If mi.DeclaringType = t Then
           DocumentMethod(doc, mi)
       End If
   Next
      ' イベント
       doc.Blocks.Add(New Heading3("Events"))
       For Each ei As EventInfo In t.GetEvents()
       If ei.DeclaringType = t Then
           DocumentEvent(doc, ei)
       End If
   Next
End Sub
コードのコピー
void DocumentType(C1Document doc, Type t)
{
  // 非パブリック/ジェネリックはスキップします
  if (!t.IsPublic || t.ContainsGenericParameters)
   return;
  // タイプ
  doc.Blocks.Add(new Heading2("Class " + t.Name));
  // プロパティ
  doc.Blocks.Add(new Heading3("Properties"));
  foreach (PropertyInfo pi in t.GetProperties())
   {
    if (pi.DeclaringType == t)
     DocumentProperty(doc, pi);
   }
  // メソッド
  doc.Blocks.Add(new Heading3("Methods"));
  foreach (MethodInfo mi in t.GetMethods())
   {
    if (mi.DeclaringType == t)
     DocumentMethod(doc, mi);
   }
  // イベント
  doc.Blocks.Add(new Heading3("Events"));
  foreach (EventInfo ei in t.GetEvents())
   {
    if (ei.DeclaringType == t)
     DocumentEvent(doc, ei);
   }
}

このメソッドは、クラス名を含む Heading2 段落を追加し、次にリフレクションを使用してすべてのパブリックプロパティ、イベント、およびメソッドを列挙します。これらのメソッドのコードは簡単です。

コードのコピー
Private Sub DocumentProperty(doc As C1Document, pi As PropertyInfo)
   If pi.PropertyType.ContainsGenericParameters Then
       Return
   End If
   doc.Blocks.Add(New Heading4(pi.Name))
   Dim text = String.Format("public {0} {1} {{ {2}{3} }}", pi.PropertyType.Name, pi.Name, If(pi.CanRead, "get; ", String.Empty), If(pi.CanWrite, "set; ", String.Empty))
   doc.Blocks.Add(New Normal(text))
End Sub
コードのコピー
void DocumentProperty(C1Document doc, PropertyInfo pi)
{
  if (pi.PropertyType.ContainsGenericParameters)
   return;
  doc.Blocks.Add(new Heading4(pi.Name));
  var text = string.Format("public {0} {1} {{ {2}{3} }}",
   pi.PropertyType.Name,
   pi.Name,
   pi.CanRead ? "get; " : string.Empty,
   pi.CanWrite ? "set; " : string.Empty);
  doc.Blocks.Add(new Normal(text));
}

このメソッドは、プロパティ名を含む Heading4 段落を追加し、次にプロパティタイプ、名前、およびアクセサを含む Normal テキストを追加します。

イベントとプロパティを記述するために使用するメソッドは似ています。

コードのコピー
Private Sub DocumentMethod(doc As C1Document, mi As MethodInfo)
   If mi.IsSpecialName Then
       Return
   End If
   doc.Blocks.Add(New Heading4(mi.Name))
   Dim parms = New StringBuilder()
   For Each parm As var In mi.GetParameters()
       If parms.Length > 0 Then
           parms.Append(", ")
       End If
       parms.AppendFormat("{0} {1}", parm.ParameterType.Name, parm.Name)
   Next
   Dim text = String.Format("public {0} {1}({2})", mi.ReturnType.Name, mi.Name, parms.ToString())
   doc.Blocks.Add(New Normal(text))
End Sub
Private Sub DocumentEvent(doc As C1Document, ei As EventInfo)
   doc.Blocks.Add(New Heading4(ei.Name))
   Dim text = String.Format("public {0} {1}", ei.EventHandlerType.Name, ei.Name)
   doc.Blocks.Add(New Normal(text))
End Sub
コードのコピー
void DocumentMethod(C1Document doc, MethodInfo mi)
{
  if (mi.IsSpecialName)
   return;
  doc.Blocks.Add(new Heading4(mi.Name));
  var parms = new StringBuilder();
  foreach (var parm in mi.GetParameters())
   {
    if (parms.Length > 0)
     parms.Append(", ");
    parms.AppendFormat("{0} {1}", parm.ParameterType.Name, parm.Name);
   }
  var text = string.Format("public {0} {1}({2})",
   mi.ReturnType.Name,
   mi.Name,
   parms.ToString());
  doc.Blocks.Add(new Normal(text));
}
void DocumentEvent(C1Document doc, EventInfo ei)
{
  doc.Blocks.Add(new Heading4(ei.Name));
  var text = string.Format("public {0} {1}",
   ei.EventHandlerType.Name,
   ei.Name);
  doc.Blocks.Add(new Normal(text));
}

ここでプロジェクトを実行すると、次のようなウィンドウが表示されます。

結果のドキュメントは、他と同様に C1RichTextBox で表示および編集できます。C1RichTextBox の Html プロパティを使用して、これを HTML にエクスポートしたり、クリップボードを使用して Microsoft Word、Excel などのアプリケーションにコピーすることもできます。

同じテクニックを使用して、データベースから取得したデータに基づくレポートを作成することもできます。書式設定されたテキストに加えて、C1Document オブジェクトモデルは以下の機能をサポートします。