FlexGrid for WinForms | ComponentOne
Tree Grid / Customize Tree Grid
In This Topic
    Customize Tree Grid
    In This Topic

    FlexGrid allows you to customize Tree Grid by styling as well as by using various elements like checkboxes to expand/collapse nodes or images as node icons. A customized Tree Grid can make the outline tree nodes look more distinctive and structured making it visually appealing and more understandable.

    Style Tree Grid

    Styling a Tree Grid is similar to styling the FlexGrid control. The Tree property returns a reference to a GridTree object that exposes several methods and properties used to customize the Tree Grid. Following is the list of some commonly used properties.

    For more information on styling the tree grid, see Styling and Appearance topic in FlexGrid documentation.

    Display Tree with CheckBoxes

    To create a custom Tree Grid with checkbox and images, you need to first initialize FlexGrid for creating Tree Grid and then add nodes to the tree by using AddNode method of the RowCollection class.

    Now, to implement checkboxes in Tree Grid, you need to maintain the checkboxes in parent and child nodes. This method uses Checked property of the Node class which defines whether to show a checkbox for the node or not.

    Tree with Checkboxes

      The code below shows how to display checkboxes on tree nodes of the WinForms Tree Grid.
    void c1FlexGrid1_CellChecked(object sender, C1.Win.C1FlexGrid.RowColEventArgs e)
     {
       // Apply check value to all children
       var node = this.c1FlexGrid1.Rows[e.Row].Node;
       UpdateCheckChildren(node);
      // Apply check value to parents
       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)
    {
       // Gets this node's parent
       var parent = node.Parent;
       if (parent != null)
       {
         // Counts checked/unchecked children
         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;
           }
         }
        // Updates parent's check state
         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;
         }
         // Updates grandparent as well
           UpdateCheckParent(parent);
         }
     }              
    
        Private Sub c1FlexGrid1_CellChecked(ByVal sender As Object, ByVal e As C1.Win.C1FlexGrid.RowColEventArgs)
            ' Apply check value to all children
            Dim node = Me.c1FlexGrid1.Rows(e.Row).Node
            UpdateCheckChildren(node)
            ' Apply check value to parents
            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)
            ' Gets this node's parent
            Dim parent = node.Parent
    
            If parent IsNot Nothing Then
                ' Counts checked/unchecked children
                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
    
                ' Updates parent's check state
                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
    
                ' Updates grandparent as well
                UpdateCheckParent(parent)
            End If
        End Sub        
    

    Display Tree with Images

    To add the images as your Tree Grid node icons, you can use the AddImageFolder method for creating nodes related to files and assigning images to the nodes.

    Tree with Images

    Use the code below to display images or icons along with nodes of the WinForms Tree Grid.

    void AddImageFolder(string path, int level)
    {
     int cnt = 0;
     try
     {
       //Loops through all files in the directory
       foreach (string file in Directory.GetFiles(path))
       {
        //Creates node for each file and adds it to FlexGrid
        var node = c1FlexGrid2.Rows.AddNode(level); 
        //sets data for the node created
        node.Data = Path.GetFileName(file);
                       
        //Code for assigning image to the node
        ShowImage(node, file);
        //show only 20 files (at max) from each directory
        cnt++;
        if (cnt > 20) break;
        }
      }
        catch { }
        try
        {
          //Loops through all sub-directories for the path
          foreach (string subPath in Directory.GetDirectories(path))
          {
           //Creates node for each file and adds it to FlexGrid
           var node = c1FlexGrid2.Rows.AddNode(level);
           //Sets data for the node created
           node.Data = Path.GetFileName(subPath);
           //Code for assigning image to the node
           ShowImage(node, subPath);
           //Traverse any sub-directory/files for the current directory
           AddImageFolder(subPath, level + 1);
           //Show only 20 files (at max) from each directory
           cnt++;
           if (cnt > 20) break;
           }
         }
          catch { }
    }                 
    
    Private Sub AddImageFolder(ByVal path As String, ByVal level As Integer)
        Dim cnt As Integer = 0
    
        Try
    
            'Loops through all files in the directory
            For Each file As String In Directory.GetFiles(path)
                'Creates node for each file and adds it to FlexGrid
                Dim node = c1FlexGrid2.Rows.AddNode(level)
                'sets data for the node created
                node.Data = Path.GetFileName(file)
    
                'Code for assigning image to the node
                ShowImage(node, file)
                'show only 20 files (at max) from each directory
                cnt += 1
                If cnt > 20 Then Exit For
            Next
    
        Catch
        End Try
    
        Try
    
            'Loops through all sub-directories for the path
            For Each subPath As String In Directory.GetDirectories(path)
                'Creates node for each file and adds it to FlexGrid
                Dim node = c1FlexGrid2.Rows.AddNode(level)
                'Sets data for the node created
                node.Data = Path.GetFileName(subPath)
                'Code for assigning image to the node
                ShowImage(node, subPath)
                'Traverse any sub-directory/files for the current directory
                AddImageFolder(subPath, level + 1)
                'Show only 20 files (at max) from each directory
                cnt += 1
                If cnt > 20 Then Exit For
            Next
    
        Catch
        End Try
    End Sub         
    

    The above code uses a custom method called ShowImage to set the image for nodes based on its file extensions.

    public void ShowImage(C1.Win.C1FlexGrid.Node node , string path)
     {
          //Gets file extension from the path
         string extension = Path.GetExtension(path);
         //If path belongs to a file
          if (extension != "")
          {
            //Sets Image for node based on the file 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 path belongs to a directory/folder
            else
            {
               node.Image = Properties.Resources.Folder;
            }
     }          
    
    Public Sub ShowImage(ByVal node As C1.Win.C1FlexGrid.Node, ByVal path As String)
        'Gets file extension from the path
        Dim extension As String = Path.GetExtension(path)
    
        'If path belongs to a file
        If Not Equals(extension, "") Then
    
            'Sets Image for node based on the file extension
            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
                    'Else path belongs to a directory/folder
            End Select
        Else
            node.Image = Properties.Resources.Folder
        End If
    End Sub         
    

    Similarly, you can show image and checkbox together for the tree nodes of the TreeGrid by setting both the Checked and Image properties of the Node Class.

    See Also