Paul Bang-Jensen Paul Bang-Jensen - 2 months ago 20
Vb.net Question

3 layers Treeview Nodes Checkboxes

I have a 3 layer treeview and is using the code below. I am getting it to do the following,

1) If parent is checked, check all child nodes.

2) If just one child node is unchecked, uncheck parent node.

3) If all child nodes are checked, check parent node.

Code below only works for 2 layers. Would appreciate if you can guide me how to make it three. There are much information on treeview but most of them seems irrelevant =/ Will be great if you can show me a good guide on treeview control. Thank you!

Private Sub TreeView1_AfterCheck(ByVal sender As Object, ByVal e As TreeViewEventArgs) Handles TreeView1.AfterCheck
RemoveHandler TreeView1.AfterCheck, AddressOf TreeView1_AfterCheck

For Each node As TreeNode In e.Node.Nodes
node.Checked = e.Node.Checked
Next

If e.Node.Checked Then
If e.Node.Parent Is Nothing = False Then
Dim allChecked As Boolean = True

For Each node As TreeNode In e.Node.Parent.Nodes
If Not node.Checked Then
allChecked = False
End If
Next

If allChecked Then
e.Node.Parent.Checked = True
End If

End If
Else
If e.Node.Parent Is Nothing = False Then
e.Node.Parent.Checked = False
End If
End If

AddHandler TreeView1.AfterCheck, AddressOf TreeView1_AfterCheck
End Sub

Answer

Working example using recursion:

Public Class Form1

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    For i As Integer = 1 To 3
      Dim node As New TreeNode("Parent #" & i.ToString)
      node.Nodes.Add("Child #1")
      node.Nodes.Add("Child #2")

      Dim childNode As New TreeNode("Child #3")
      childNode.Nodes.Add("Grand Child #1")
      childNode.Nodes.Add("Grand Child #2")

      Dim grandNode As New TreeNode("Grand Child #3")
      grandNode.Nodes.Add("Great Grand Child #1")
      grandNode.Nodes.Add("Great Grand Child #2")
      childNode.Nodes.Add(grandNode)
      node.Nodes.Add(childNode)

      grandNode.Expand()
      childNode.Expand()
      node.Expand()

      TreeView1.Nodes.Add(node)
    Next
  End Sub

  Private Sub TreeView1_AfterCheck(ByVal sender As Object, ByVal e As TreeViewEventArgs) Handles TreeView1.AfterCheck
    RemoveHandler TreeView1.AfterCheck, AddressOf TreeView1_AfterCheck

    Call CheckAllChildNodes(e.Node)

    If e.Node.Checked Then
      If e.Node.Parent Is Nothing = False Then
        Dim allChecked As Boolean = True
        Call IsEveryChildChecked(e.Node.Parent, allChecked)
        If allChecked Then
          e.Node.Parent.Checked = True
          Call ShouldParentsBeChecked(e.Node.Parent)
        End If
      End If
    Else
      Dim parentNode As TreeNode = e.Node.Parent
      While parentNode Is Nothing = False
        parentNode.Checked = False
        parentNode = parentNode.Parent
      End While
    End If

    AddHandler TreeView1.AfterCheck, AddressOf TreeView1_AfterCheck
  End Sub

  Private Sub CheckAllChildNodes(ByVal parentNode As TreeNode)
    For Each childNode As TreeNode In parentNode.Nodes
      childNode.Checked = parentNode.Checked
      CheckAllChildNodes(childNode)
    Next
  End Sub

  Private Sub IsEveryChildChecked(ByVal parentNode As TreeNode, ByRef checkValue As Boolean)
    For Each node As TreeNode In parentNode.Nodes
      Call IsEveryChildChecked(node, checkValue)
      If Not node.Checked Then
        checkValue = False
      End If
    Next
  End Sub

  Private Sub ShouldParentsBeChecked(ByVal startNode As TreeNode)
    If startNode.Parent Is Nothing = False Then
      Dim allChecked As Boolean = True
      Call IsEveryChildChecked(startNode.Parent, allChecked)
      If allChecked Then
        startNode.Parent.Checked = True
        Call ShouldParentsBeChecked(startNode.Parent)
      End If
    End If
  End Sub

End Class
Comments