FlexGrid for WinForms
ツリーグリッドのカスタマイズ
ツリーグリッド > ツリーグリッドのカスタマイズ

FlexGrid では、スタイルを設定したり、ノードを展開/折りたたむチェックボックスのような要素やノードアイコンのような画像を使用することで、ツリーグリッドをカスタマイズできます。ツリーグリッドをカスタマイズすると、アウトラインツリーノードをより明確に構造化して表示できるため、見栄えがよくなると共に、読み取りやすくなります。

ツリーグリッドのスタイル設定

ツリーグリッドのスタイル設定は、FlexGrid コントロールのスタイル設定に似ています。 Tree プロパティは、ツリーグリッドのカスタマイズに使用されるメソッドやプロパティを公開する GridTree オブジェクトへの参照を返します。以下は、よく使用されるプロパティのリストです。

ツリーグリッドのスタイル設定の詳細については、FlexGrid のドキュメントのトピック「スタイル設定と外観」を参照してください。

チェックボックスを持つツリーの表示

チェックボックスや画像を持つツリーグリッドを作成するには、最初に、ツリーグリッドを作成するための FlexGrid を初期化した後、RowCollection クラスの AddNode メソッドを使用してツリーにノードを追加します。

次に、ツリーグリッドでチェックボックスを実装するには、親および子ノードでチェックボックスを保持する必要があります。この方法では、Node クラスの Checked プロパティを使用して、ノードにチェックボックスを表示するかどうかを定義します。

チェックボックスを持つツリー

  次のコードは、WinForms ツリーグリッドのツリーノードにチェックボックスを表示する方法を示します。
void c1FlexGrid1_CellChecked(object sender, C1.Win.C1FlexGrid.RowColEventArgs e)
 {
   // すべての子にチェック値を適用します
   var node = this.c1FlexGrid1.Rows[e.Row].Node;
   UpdateCheckChildren(node);
  // 親にチェック値を適用します
   UpdateCheckParent(node);
 }
void UpdateCheckChildren(C1.Win.C1FlexGrid.Node node)
 {
    var checkState = node.Checked;
    foreach (C1.Win.C1FlexGrid.Node child in node.Nodes)
   {
     child.Checked = checkState;
     UpdateCheckChildren(child);
    }
 }
void UpdateCheckParent(C1.Win.C1FlexGrid.Node node)
{
   // このノードの親を取得します
   var parent = node.Parent;
   if (parent != null)
   {
     // チェックされた/チェックされていない子をカウントします
     int cntChecked = 0;
     int cntUnchecked = 0;
     int cntGrayed = 0;
     foreach (C1.Win.C1FlexGrid.Node child in parent.Nodes)
    {
      switch (child.Checked)
      {
        case C1.Win.C1FlexGrid.CheckEnum.Checked:
             cntChecked++;
             break;
        case C1.Win.C1FlexGrid.CheckEnum.Unchecked:
             cntUnchecked++;
             break;
        case C1.Win.C1FlexGrid.CheckEnum.Grayed:
             cntGrayed++;
             break;
       }
     }
    // 親のチェック状態を更新します
     if (cntGrayed > 0 || (cntChecked > 0 && cntUnchecked > 0))
     {
       parent.Checked = C1.Win.C1FlexGrid.CheckEnum.Grayed;
     }
     else if (cntChecked > 0 && cntUnchecked == 0)
     {
       parent.Checked = C1.Win.C1FlexGrid.CheckEnum.Checked;
     }
     else if (cntUnchecked > 0 && cntChecked == 0)
     {
       parent.Checked = C1.Win.C1FlexGrid.CheckEnum.Unchecked;
     }
     // 祖父も更新します
       UpdateCheckParent(parent);
     }
 }        
Private Sub c1FlexGrid1_CellChecked(ByVal sender As Object, ByVal e As C1.Win.C1FlexGrid.RowColEventArgs)
        ' すべての子にチェック値を適用します
        Dim node = Me.c1FlexGrid1.Rows(e.Row).Node
        UpdateCheckChildren(node)
        ' 親にチェック値を適用します
        UpdateCheckParent(node)
    End Sub
    Private Sub UpdateCheckChildren(ByVal node As C1.Win.C1FlexGrid.Node)
        Dim checkState = node.Checked
        For Each child As C1.Win.C1FlexGrid.Node In node.Nodes
            child.Checked = checkState
            Me.UpdateCheckChildren(child)
        Next
    End Sub
    Private Sub UpdateCheckParent(ByVal node As C1.Win.C1FlexGrid.Node)
        ' このノードの親を取得します
        Dim parent = node.Parent
        If parent IsNot Nothing Then
            ' チェックされた/チェックされていない子をカウントします
            Dim cntChecked As Integer = 0
            Dim cntUnchecked As Integer = 0
            Dim cntGrayed As Integer = 0
            For Each child As C1.Win.C1FlexGrid.Node In parent.Nodes
                Select Case child.Checked
                    Case C1.Win.C1FlexGrid.CheckEnum.Checked
                        cntChecked += 1
                    Case C1.Win.C1FlexGrid.CheckEnum.Unchecked
                        cntUnchecked += 1
                    Case C1.Win.C1FlexGrid.CheckEnum.Grayed
                        cntGrayed += 1
                End Select
            Next
            ' 親のチェック状態を更新します
            If cntGrayed > 0 OrElse cntChecked > 0 AndAlso cntUnchecked > 0 Then
                parent.Checked = C1.Win.C1FlexGrid.CheckEnum.Grayed
            ElseIf cntChecked > 0 AndAlso cntUnchecked = 0 Then
                parent.Checked = C1.Win.C1FlexGrid.CheckEnum.Checked
            ElseIf cntUnchecked > 0 AndAlso cntChecked = 0 Then
                parent.Checked = C1.Win.C1FlexGrid.CheckEnum.Unchecked
            End If
            ' 祖父も更新します
            UpdateCheckParent(parent)
        End If
    End Sub        

画像を持つツリーの表示

ツリーグリッドのノードアイコンとして画像を追加するには、AddImageFolder メソッドを使用して、ファイルに関連付けられたノードを作成し、画像をノードに割り当てます。

画像を含むツリー

次のコードを使用して、WinForms ツリーグリッドのノードと一緒に画像またはアイコンを表示できます。

void AddImageFolder(string path, int level)
{
 int cnt = 0;
 try
 {
   //ディレクトリ内のすべてのファイルをループします
   foreach (string file in Directory.GetFiles(path))
   {
    //ファイルごとにノードを作成し、FlexGridに追加します
    var node = c1FlexGrid2.Rows.AddNode(level); 
    //作成されたノードのデータを設定します
    node.Data = Path.GetFileName(file);
                   
    //画像をノードに割り当てるためのコード
    ShowImage(node, file);
    //各ディレクトリから(最大で)20個のファイルのみを表示します
    cnt++;
    if (cnt > 20) break;
    }
  }
    catch { }
    try
    {
      //パスのすべてのサブディレクトリをループします
      foreach (string subPath in Directory.GetDirectories(path))
      {
       //ファイルごとにノードを作成し、FlexGridに追加します
       var node = c1FlexGrid2.Rows.AddNode(level);
       //作成されたノードのデータを設定します
       node.Data = Path.GetFileName(subPath);
       //画像をノードに割り当てるためのコード
       ShowImage(node, subPath);
       //現在のディレクトリのサブディレクトリ/ファイルをトラバースします
       AddImageFolder(subPath, level + 1);
       //各ディレクトリから(最大で)20個のファイルのみを表示します
       cnt++;
       if (cnt > 20) break;
       }
     }
      catch { }
}        
Private Sub AddImageFolder(ByVal path As String, ByVal level As Integer)
    Dim cnt As Integer = 0
    Try
        'ディレクトリ内のすべてのファイルをループします
        For Each file As String In Directory.GetFiles(path)
            'ファイルごとにノードを作成し、FlexGridに追加します
            Dim node = c1FlexGrid2.Rows.AddNode(level)
            '作成されたノードのデータを設定します
            node.Data = Path.GetFileName(file)
            '画像をノードに割り当てるためのコード
            ShowImage(node, file)
            '各ディレクトリから(最大で)20個のファイルのみを表示します
            cnt += 1
            If cnt > 20 Then Exit For
        Next
    Catch
    End Try
    Try
        'パスのすべてのサブディレクトリをループします
        For Each subPath As String In Directory.GetDirectories(path)
            'ファイルごとにノードを作成し、FlexGridに追加します
            Dim node = c1FlexGrid2.Rows.AddNode(level)
            '作成されたノードのデータを設定します
            node.Data = Path.GetFileName(subPath)
            '画像をノードに割り当てるためのコード
            ShowImage(node, subPath)
            '現在のディレクトリのサブディレクトリ/ファイルをトラバースします
            AddImageFolder(subPath, level + 1)
            '各ディレクトリから(最大で)20個のファイルのみを表示します
            cnt += 1
            If cnt > 20 Then Exit For
        Next
    Catch
    End Try
End Sub         

上のコードでは、ShowImage というカスタムメソッドを使用して、ファイル拡張子に基づいてノードの画像を設定しています。

public void ShowImage(C1.Win.C1FlexGrid.Node node , string path)
 {
      //パスからファイル拡張子を取得します
     string extension = Path.GetExtension(path);
     //パスがファイルに属している場合
      if (extension != "")
      {
        //ファイル拡張子に基づいてノードの画像を設定します
        switch (extension)
        {
          case ".txt":
               node.Image = Properties.Resources.Txt;
               break;
         case ".resx":
               node.Image = Properties.Resources.Txt;
               break;
          case ".licx":
               node.Image = Properties.Resources.Txt;
               break;
          case ".cs":
               node.Image = Properties.Resources.Txt;
               break;
          case ".vb":
               node.Image = Properties.Resources.Txt;
               break;
          case ".exe":
               node.Image = Properties.Resources.Exe;
               break;
          case ".dll":
               node.Image = Properties.Resources.Dll;
               break;
          case ".sln":
               node.Image = Properties.Resources.VS;
               break;
          case ".csproj":
               node.Image = Properties.Resources.VS;
               break;
          case ".bmp":
               node.Image = Properties.Resources.Img;
               break;
          case ".png":
               node.Image = Properties.Resources.Img;
               break;
          case ".gif":
               node.Image = Properties.Resources.Video;
               break;
          case ".accdb":
               node.Image = Properties.Resources.Access;
               break;
          default:
               node.Image = Properties.Resources.Unknown;
               break;
          }
        }
        //それ以外のパスはディレクトリ/フォルダに属しています
        else
        {
           node.Image = Properties.Resources.Folder;
        }
 }          
Public Sub ShowImage(ByVal node As C1.Win.C1FlexGrid.Node, ByVal path As String)
    'パスからファイル拡張子を取得します
    Dim extension As String = Path.GetExtension(path)
    'パスがファイルに属している場合
    If Not Equals(extension, "") Then
        'ファイル拡張子に基づいてノードの画像を設定します
        Select Case extension
            Case ".txt"
                node.Image = Properties.Resources.Txt
            Case ".resx"
                node.Image = Properties.Resources.Txt
            Case ".licx"
                node.Image = Properties.Resources.Txt
            Case ".cs"
                node.Image = Properties.Resources.Txt
            Case ".vb"
                node.Image = Properties.Resources.Txt
            Case ".exe"
                node.Image = Properties.Resources.Exe
            Case ".dll"
                node.Image = Properties.Resources.Dll
            Case ".sln"
                node.Image = Properties.Resources.VS
            Case ".csproj"
                node.Image = Properties.Resources.VS
            Case ".bmp"
                node.Image = Properties.Resources.Img
            Case ".png"
                node.Image = Properties.Resources.Img
            Case ".gif"
                node.Image = Properties.Resources.Video
            Case ".accdb"
                node.Image = Properties.Resources.Access
            Case Else
                node.Image = Properties.Resources.Unknown
                'それ以外のパスはディレクトリ/フォルダに属しています
        End Select
    Else
        node.Image = Properties.Resources.Folder
    End If
End Sub         
関連トピック