VB.NET - Check if child node if checked in TreeView - vb.net

I am using Visual Basic .NET 2013 and I want to know which child nodes are checked in a treeview. I don't check parent nodes because the checkboxes are only in child nodes (I have disabled checkboxes in parent nodes, so they don't appear).
At the moment I am using one solution I found:
Private Sub TreeView1_AfterCheck(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterCheck
Dim childNodeCK As TreeNode = e.Node
If childNodeCK.Checked = True Then
If e.Node.Parent Is Nothing = False Then 'detects a Child Node
TextBox1.Text = TextBox1.Text & childNodeCK.Text
MessageBox.Show("Checked: " & childNodeCK.Text)
End If
End If
If childNodeCK.Checked = False Then
If e.Node.Parent Is Nothing = False Then
MessageBox.Show("Unchecked: " & childNodeCK.Text)
End If
End If
End Sub
But I want to know if there is another solution, something like this (the following code doesn't show anything because when I click a button to run it, nothing happens):
For Each childNode As System.Windows.Forms.TreeNode In TreeView1.Nodes
If childNode.Checked = True Then
MessageBox.Show(childNode.Text)
End If
Next
because the idea is to click a button and obtain the name (text) of the child nodes that are checked at that moment. So I think I have to check one by one from the beginning to the end and if the child node is checked then execute some code.

To get all of the checked nodes, you would have to use a recursive function or a stacked list. I prefer the latter:
Private Function GetCheckedNodes() As List(Of TreeNode)
Dim result As New List(Of TreeNode)
'Get the root nodes
Dim nodes As New Stack(Of TreeNode)
For Each tn As TreeNode In TreeView1.Nodes
nodes.Push(tn)
Next
'Check each node and it's children
While nodes.Count > 0
Dim popNode As TreeNode = nodes.Pop
If popNode.Checked Then
result.Add(popNode)
End If
For Each tn As TreeNode In popNode.Nodes
nodes.Push(tn)
Next
End While
Return result
End Function
Then to use it:
For Each tn As TreeNode In GetCheckedNodes()
MessageBox.Show(tn.Text)
Next

Related

VB.NET 2010 Treeview

I have a form with a Treeview control, I add first node pragmatically, when I add the second node the first node gets selected automatically! How to stop that, I dont need any node to be selected unless I select it.
The code i use:
Dim Scr As New TreeNode()
Scr.Text = ObjScreen.ScreenDescription
Scr.Tag = ObjScreen
Scr.SelectedImageIndex = 0
Scr.ImageIndex = 0
tvScreens.Nodes.Add(Scr)
Add this:
Dim Activator as boolean
Private Sub TreeView_BeforeSelect(sender As Object, e As TreeViewCancelEventArgs) Handles TreeView.BeforeSelect
If Activator Then
e.Cancel = True
End if
End Sub
Just set activator to true at the beginning of your code that adds nodes, and false it at the end.

How to Show appropriate form When Clicking Tree view child node in VB.net

I have Tree view that have 2 Root(Masters, Transactions) node and Each Root have 1 Child(See Tree view in Image)
Masters->Party master
Transactions->Order Acceptance
I want to Display frmPartymaster.vb form when clicking Party Master(child node)
and
Display frmorder.vb form when clicking Order Acceptance(child node)
I Tried Tree view After Select event(see below code)
Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
For Each node As TreeNode In Me.TreeView1.Nodes
GetChildren(node)
Next node
End Sub
Function GetChildren(ByVal parentNode As TreeNode) As List(Of String)
Dim nodes As List(Of String) = New List(Of String)
GetAllChildren(parentNode, nodes)
Return nodes
End Function
Sub GetAllChildren(ByVal parentNode As TreeNode, ByVal nodes As List(Of String))
For Each childNode As TreeNode In parentNode.Nodes
nodes.Add(childNode.Text)
GetAllChildren(childNode, nodes)
Next
End Sub
Above Code returns all childnode's names in Return nodes variable
Now I am Looking for
how to use nodes variable values
And how to show appropriate form when clicking child
node(I know child node haven't click event)
Tell me any other efficient way found instead of afterselect event
because it loop through all root node and child node each time
According to the code you provided, you are not even trying to instantiate another class depending on what node you have selected. All that is doing is adding nodes to a list, this is not needed...
This solution you can add any class where its type is Form.
There are a few ways this can be accomplished, but I just provided one way to do what you would like to achieve.
Imports System.Reflection
Public Class Form1
Private Const FORM_PARTY_MASTER As String = "frmPartyMaster"
Private Const FORM_ORDER As String = "frmorder"
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim mNode As New TreeNode With {.Text = "Masters"}
mNode.Nodes.Add(New TreeNode With {.Text = "Party Masters", .Tag = FORM_PARTY_MASTER})
Dim transNode As New TreeNode With {.Text = "Transaction"}
transNode.Nodes.Add(New TreeNode With {.Text = "Order/Acceptance", .Tag = FORM_ORDER})
TreeView1.Nodes.AddRange({mNode, transNode})
End Sub
Private Sub TreeView1_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterSelect
Dim obj As Form
Try
If e.Node.Tag IsNot Nothing Then
obj = CType(Activator.CreateInstance(Type.GetType("WindowsApplication5." & e.Node.Tag.ToString, False)), Form)
If obj IsNot Nothing Then
Using obj
obj.ShowDialog()
End Using
End If
End If
Catch ex As Exception
'handle your exception
End Try
End Sub
End Class
Explanation
Create some constants that would represent your forms.
The load routine was just to populate the data. You will notice I use the Tag property of the TreeNode, we will use this to get an instance of what form we would need.
The AfterSelect event is used. You will see how I create an instance of whatever control you would need; no case or if statements.
Make sure you change WindowsApplication5 to what your namespace would be.

check parent when all its nodes are checked and check all nodes when their parent is checked throws error

I have tried this code:
Private Sub TreeView1_AfterCheck(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterCheck
Dim blnUncheck As Boolean = False
Dim tn As TreeNode
If e.Node.Nodes.Count = 0 Then
For Each child As TreeNode In e.Node.Parent.Nodes
If child.Checked = False Then
blnUncheck = True
End If
Next
If blnUncheck = False Then
e.Node.Parent.Checked = True
Else
e.Node.Parent.Checked = False
End If (the code above is used to check parent when nodes are checked)
Else (the code below is used to check nodes of parent when parent is checked)
If e.Node.Checked = True Then
For Each tn In e.Node.Nodes
tn.Checked = True
Next
Else
For Each tn In e.Node.Nodes
tn.Checked = False
Next
End If
End If
End Sub
in order to: a) check all nodes when their parent is checked
b) check parent when all it's nodes are checked
Although when when I remove one of two(a,b) from the code it works
When I combine them(as the code I have written), it throws a stackoverflow exception.
The code is used in treeview with checkboxes.
EDIT: SOLVED
Visit this linkTreeView.BeforeCheck Event for help (read carefully)
If you try and step through your code you will see that every time you try and check/uncheck a node, you reenter the event.
Try adding this check:
If e.Action = TreeViewAction.Unknown Then
Exit Sub
End If
If you havent manually clicked (EDIT: Also works for selecting by keypress) the node it will exit the event and stop the infinite loop
i think you are looking for that You can try ....
Private Sub CheckAllChildNodes(treeNode As TreeNode, nodeChecked As Boolean)
Dim node As TreeNode
For Each node In treeNode.Nodes
node.Checked = nodeChecked
If node.Nodes.Count > 0 Then
Me.CheckAllChildNodes(node, nodeChecked)
End If
Next node
End Sub
Private Sub node_AfterCheck(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterCheck
If e.Action <> TreeViewAction.Unknown Then
If e.Node.Nodes.Count > 0 Then
Me.CheckAllChildNodes(e.Node, e.Node.Checked)
Else
e.Node.Parent.Checked = True
End If
End If
End Sub

Display all child nodes of selected node of treeview in textbox in vb.net

Not too sure on how to get around this.
I am able to display the current selected node in a textbox (or richtextbox) by doing the following:
Private Sub TreeView1_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterSelect
RichTextBox1.Text = e.Node.Text
End Sub
However, I can't figure out a way of displaying all child nodes of the selected parent.
Would anyone be able to point me in the right direction?
You need what is called a recursive subroutine to drill down into the child nodes of each node to iterate through them:
Private Sub TreeView1_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterSelect
Dim myNode As TreeNode = e.Node
TextBox1.Text = myNode.Text
GetChildNodes(myNode)
End Sub
Sub GetChildNodes(tnode As TreeNode)
'Iterate through the child nodes of the node passed into this subroutine
For Each node As TreeNode In tnode.Nodes
TextBox1.Text += node.Text
'If the node passed into this subroutine contains child nodes,
'call the subroutine for each one of them
'If you only want to display one level deep, then comment out the
'IF statement.
If tnode.Nodes.Count > 0 Then GetChildNodes(node)
Next
End Sub

check all items under a parent node in Visual Basic

I am trying to check all the childnodes under a parent node, the code I have so far only goes about 2-3 levels deep in the TreeView and I am looking to grab all nodes no matter how deep they are. Could someone shed some insight on this.
Below is the code:
Private Sub CheckChildNode(ByVal currNode As TreeNode)
'set the children check status to the same as the current node
Dim checkStatus As Boolean = currNode.Checked
For Each node As TreeNode In currNode.Nodes
node.Checked = checkStatus
CheckChildNode(node)
Next
End Sub
Private Sub CheckParentNode(ByVal currNode As TreeNode)
Dim parentNode As TreeNode = currNode.Parent
If parentNode Is Nothing Then Exit Sub
parentNode.Checked = True
For Each node As TreeNode In parentNode.Nodes
If Not node.Checked Then
parentNode.Checked = False
Exit For
End If
Next
CheckParentNode(parentNode)
End Sub
Private Sub treeview_AfterCheck(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.TreeViewEventArgs) Handles treeview.AfterCheck
RemoveHandler treeview.AfterCheck, AddressOf treeview_AfterCheck
CheckChildNode(e.Node)
CheckParentNode(e.Node)
AddHandler treeview.AfterCheck, AddressOf treeview_AfterCheck
End Sub
In order to get all subnodes no matter how deep they are, you definitely need recursion.
That is, you take each direct child of a node and do the check for this node. And you also call the method to check subnodes for each child.
So here in Pseudocode.
node getParentNode(node child){
return child.parent
}
node checkNode(node n){
// perform check here for node n
if n is not valid {
return false!
}
// do children recursively
for each child in n.children{
// function calls itself!
checkNode(child)
}
}
Here's a recursion tutorial for vb.net. Here, here and here is you can find additional information.