My treeview looks like this:
ParentNode
Childnode1
Childnode2
Childnode3 < I want to get the text of this node when you click on the parentnode
Childnode4
Childnode5
Thanks
It is as simple as using the indexer property of the Nodes collection of your node, like this:
YourNode.Nodes(2).Text
If you have handled NodeMouseClick event of your TreeView, the second parameter e as TreeNodeMouseClickEventArgs can be used like this:
Public Sub YourTreeView_AfterSelect(sender As Object, e As System.Windows.Forms.TreeNodeMouseClickEventArgs)
If YourTreeView.SelectedNode.Nodes.Count > 2 Then
MsgBox(YourTreeView.SelectedNode.Nodes(2).Text)
Else
MsgBox("No 3rd node is available.")
End Sub
Got what I was looking for thanks to #dotNET
Private Sub TreeView1_Click(sender As Object, e As EventArgs) Handles TreeView1.AfterSelect
If TreeView1.SelectedNode IsNot Nothing AndAlso TreeView1.SelectedNode.Nodes.Count > 2 Then
Link = TreeView1.SelectedNode.Nodes(2).Text
End If
End Sub
Thanks
Related
I am working with forms in VB.NET
There is a DatagridView table with a checkbox column.
See the picture below:
I am interested in the question: how to add the line index to the list when clicking in the checkbox (when we activate the checked status), and remove it from the list when we uncheck the checkbox?
Tried the following but this is not the correct solution:
If e.ColumnIndex = chk_column.Index Then
If e.RowIndex >= 0 Then
Try
For Each row As DataGridViewRow In dataGridNames.Rows
Dim cell As DataGridViewCheckBoxCell = TryCast(row.Cells(5), DataGridViewCheckBoxCell)
If cell.Value Is cell.FalseValue Then
bList_indexes.Add(DataGridnames.CurrentCell.RowIndex)
Exit For
Else 'If cell.Value Is cell.TrueValue Then
bList_indexes.RemoveAt(DataGridnames.CurrentCell.RowIndex)
End If
Next
Catch ex As Exception
'Show the exception's message.
'MessageBox.Show(ex.Message)
'Throw New Exception("Something happened.")
End try
End If
End If
Using DataSources allows you to take the logic out of mucking around in DataGridView events. You shouldn't perform [much] business logic on the UI anyways.
Here is the class I used to represent your data.
Public Class ClassWithSelect
Public Property [Select] As Boolean
Public Property Name As String
Public Sub New(s As Boolean, n As String)
Me.Select = s
Me.Name = n
End Sub
End Class
And all the code to set DataSources
Private myDataSource As List(Of ClassWithSelect)
Private selectedIndices As List(Of Integer)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
myDataSource = Enumerable.Range(65, 10).Select(Function(i) New ClassWithSelect(False, Chr(i).ToString())).ToList()
DataGridView1.DataSource = myDataSource
updateSelectedIndices()
End Sub
Private Sub DataGridView1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
updateSelectedIndices()
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
End Sub
Private Sub updateSelectedIndices()
selectedIndices = New List(Of Integer)()
For i = 0 To myDataSource.Count - 1
If myDataSource(i).Select Then selectedIndices.Add(i)
Next
ListBox1.DataSource = selectedIndices
End Sub
And the end result
Now you don't need to access the UI to get the indices for further processing as they are in the class-level variable selectedIndices. The UI is meant for user I/O, NOT for storing state.
Note: The event handler was taken from this answer but this answer is also linked as an improvement to the check change handler, but I felt the complexity would distract from my answer. If you find you need to click fast, look into the latter.
Also Note: The method updateSelectedIndices() should have inside it an InvokeRequired check if you plan to perform work off the UI thread
Public Module Inv
Public Item(4) as String
End Module
Private Sub Inventory_SelectedIndexChanged(sender As Object, e As EventArgs) Handles Inventory.SelectedIndexChanged
If Inventory.SelectedIndex.ToString(Item(0)) Then
MessageBox.Show("Item Selected!")
playerDMG *= 3
End If
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs)
Item(0) = "Plasma"
for add = 0 to 0
inventory.items.add(item(add))
End Sub
What I want is that if I click that button it adds Item(0) to the listbox, and if I click on the item in the listbox it will triple playerDMG.
Problem here is that it is telling me I can't convert "Plasma Gun" to type 'Boolean'
What's going wrong here? Is there a better way to do this?
I think you would need to do something like this:
If Inventory.SelectedItem.ToString() = Item(0) Then ...
Alternatively, you could use SelectedValue I guess, but in order for that to work you'd need to use DataSource property of combobox.
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.
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
I've got a System.Windows.Forms.TreeView with HotTracking = True
I wish to set HotTracking to False only in a specific Node.
For example i would like the father to be not clickable and the children to be clickable.
Thank you
"Clickable" is pretty ambiguous. I'll assume you don't want them to be selectable. Which is easy to do with the BeforeSelect event, you can cancel it. For example:
Private Sub TreeView1_BeforeSelect(ByVal sender As Object, ByVal e As TreeViewCancelEventArgs) Handles TreeView1.BeforeSelect
If e.Node.Nodes.Count > 0 Then e.Cancel = True
End Sub
This does not make for a great user interface, the user will be very confuzzled when his click has no effect. You can make it a bit more intuitive by not throwing the click away and automatically selecting a node that you do allow to be selected. Make that look similar to this:
Private Sub TreeView1_BeforeSelect(ByVal sender As Object, ByVal e As TreeViewCancelEventArgs) Handles TreeView1.BeforeSelect
If e.Node.Nodes.Count > 0 Then
e.Cancel = True
Me.BeginInvoke(New Action(Of TreeNode)(AddressOf SelectNode), e.Node.Nodes(0))
End If
End Sub
Private Sub SelectNode(ByVal node As TreeNode)
node.Expand()
node.TreeView.SelectedNode = node
End Sub