The treeview control. Changing order of nodes

If I have 10 nodes in a treeview and each one of these nodes has 13 child nodes and those child nodes have child nods and so on how do I take node 3 and node 6 and swich them around? When they swich I need all their children to make th swich with them. To the user it will look as if these two nodes just... swich places. Thank you for your help!
LVL 5
xersoftAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jgvCommented:
This is a sample I wrote that will 'swap' two nodes w/children. It moves the selected node up or down one position based on user's choice. With some modification you would be able achive what you're looking for. If you need help doing this let me know.

To test, drop a treeview (default name) and two command buttons (cmdUp and cmdDown). Cut and paste code.

Dim tempname 'stores selected nodes text
Dim temptag  'stores selected nodes tag
Dim tempkey1 'stores selected nodes key
Dim tempkey2 'stores key for node above/below selected node
Dim nindex   'stores index used to set newnode
Dim selnode As Node 'node selected to move
Dim newnode As Node 'node above or below selected node
Dim gcheck 'used to check for children of selnode & newnode

Private Sub Form_Activate()
Dim gnode As Node
Set gnode = TreeView1.Nodes.Add(, , , "Root")
Set gnode = TreeView1.Nodes.Add(1, tvwChild, , "NodeA")
gnode.EnsureVisible
Set gnode = TreeView1.Nodes.Add(1, tvwChild, , "NodeB")
Set gnode = TreeView1.Nodes.Add(1, tvwChild, , "NodeC")
Set gnode = TreeView1.Nodes.Add(2, tvwChild, , "Anode1")
Set gnode = TreeView1.Nodes.Add(2, tvwChild, , "Anode2")
Set gnode = TreeView1.Nodes.Add(2, tvwChild, , "Anode3")
Set gnode = TreeView1.Nodes.Add(3, tvwChild, , "Bnode1")
Set gnode = TreeView1.Nodes.Add(3, tvwChild, , "Bnode2")
Set gnode = TreeView1.Nodes.Add(4, tvwChild, , "Cnode1")
Set gnode = TreeView1.Nodes.Add(4, tvwChild, , "Cnode2")
Set gnode = TreeView1.Nodes.Add(5, tvwChild, , "extra1")
Set gnode = TreeView1.Nodes.Add(6, tvwChild, , "extra2")
End Sub

Private Sub cmdUp_Click()

'make sure a node was selected
If TreeView1.SelectedItem Is Nothing Then
    MsgBox "You must select a node first.", vbOKOnly
    Exit Sub
End If

'check if selected node is 'first sibling'
If TreeView1.SelectedItem = TreeView1.SelectedItem.FirstSibling Then
    MsgBox "This is the first child", vbOKOnly
    Exit Sub
End If

'store index of node above selected node
nindex = TreeView1.SelectedItem.Previous.Index
swapnodes

End Sub

Private Sub cmdDown_Click()

'make sure a node was selected
If TreeView1.SelectedItem Is Nothing Then
    MsgBox "You must select a node first.", vbOKOnly
    Exit Sub
End If

'check if selected node is 'last sibling'
If TreeView1.SelectedItem = TreeView1.SelectedItem.LastSibling Then
    MsgBox "This is the last child", vbOKOnly
    Exit Sub
End If

'store index of node below selected node
nindex = TreeView1.SelectedItem.Next.Index
swapnodes

End Sub

Public Sub swapnodes()

' initialize selnode based on the node selected to move
' and store the info in temp variables
Set selnode = TreeView1.SelectedItem
tempname = selnode.Text
temptag = selnode.Tag
tempkey1 = selnode.Key
   
    'initialize newnode to node above or below selected
    'node
    Set newnode = TreeView1.Nodes(nindex)
    'swap info between selnode and newnode
    With selnode
        .Text = newnode.Text
        newnode.Text = tempname
        .Tag = newnode.Tag
        newnode.Tag = temptag
        .Key = "" ' set to nothing to avoid duplicates
        tempkey2 = newnode.Key ' store newnode key and swap
        newnode.Key = tempkey1
        .Key = tempkey2
    End With

'check if there are children in either or both nodes
'being swaped. gcheck indicates the children statis
If selnode.Children > 0 And newnode.Children > 0 Then
    gcheck = 1
    transfer
Else
    If selnode.Children > 0 Then
      gcheck = 2: transfer
    Else
      If newnode.Children > 0 Then
        gcheck = 3: transfer
      End If
    End If
End If
     
'newnode now contains the info for the selected node so
'make newnode the selected node so the user can keep moving
'it up or down.
Set TreeView1.SelectedItem = newnode
TreeView1.SetFocus

End Sub

Public Sub transfer()

Dim tempnode As Node

Select Case gcheck
   
   Case 1: 'both selnode and newnode contain children.
     
      'add node 'temp' to newnode's children;
      'referenced as tempnode
      Set tempnode = TreeView1.Nodes.Add _
      (newnode.Index, tvwChild, , "temp")
      'move all children from selnode to 'temp'.
      'these routines move the 'lastsibling' first to
      'maintain proper child order. once the lastsibling
      'is moved, the node that was above it becomes the
      'lastsibling until all children are moved.
      While selnode.Children > 0
          Set selnode.Child.LastSibling.Parent = tempnode
      Wend
     
      'move all children (including 'temp') from newnode
      'to selnode. You have to keep in mind that newnode's
      'info (node that was above/below node being moved)
      'moves into selnode's position (node that was selected
      'to move). the children in newnode's position belong
      'in selnode. I had to do this on paper to keep it all
      'straight.
      While newnode.Children > 0
          Set newnode.Child.LastSibling.Parent = selnode
      Wend
     
      'set tempnode to reference 'temp' which now resides
      'as the lastsibling in selnode.
      Set tempnode = TreeView1.Nodes(selnode.Child.LastSibling.Index)
     
      'move children from 'temp' to newnode.
      While tempnode.Children > 0
        Set tempnode.Child.LastSibling.Parent = newnode
      Wend
     
      'remove 'temp' now that it's empty. children are now
      'transfered.
      TreeView1.Nodes.Remove (tempnode.Index)
   
  Case 2: 'only selected node contains children
   
    While selnode.Children > 0
        Set selnode.Child.LastSibling.Parent = newnode
    Wend
   
  Case 3: 'only node above/below selected node have children
   
    While newnode.Children > 0
        Set newnode.Child.LastSibling.Parent = selnode
    Wend

End Select
   
End Sub
0
jgvCommented:
Here is a slight variation where you can specify the index of the nodes, by whatever means you are finding them, in cmdSwap. If you have any questions let me know :)

Dim node1, node2 'stores index of "nodes to swap"
Dim tempname 'stores selected nodes text
Dim temptag  'stores selected nodes tag
Dim tempkey1 'stores selected nodes key
Dim tempkey2 'stores key for node above/below selected node
Dim selnode As Node 'node selected to move
Dim newnode As Node 'node above or below selected node
Dim gcheck 'used to check for children of selnode & newnode

Private Sub Form_Activate()
Dim gnode As Node
Set gnode = TreeView1.Nodes.Add(, , , "Root")
Set gnode = TreeView1.Nodes.Add(1, tvwChild, , "NodeA")
gnode.EnsureVisible
Set gnode = TreeView1.Nodes.Add(1, tvwChild, , "NodeB")
Set gnode = TreeView1.Nodes.Add(1, tvwChild, , "NodeC")
Set gnode = TreeView1.Nodes.Add(2, tvwChild, , "Anode1")
Set gnode = TreeView1.Nodes.Add(2, tvwChild, , "Anode2")
Set gnode = TreeView1.Nodes.Add(2, tvwChild, , "Anode3")
Set gnode = TreeView1.Nodes.Add(3, tvwChild, , "Bnode1")
Set gnode = TreeView1.Nodes.Add(3, tvwChild, , "Bnode2")
Set gnode = TreeView1.Nodes.Add(4, tvwChild, , "Cnode1")
Set gnode = TreeView1.Nodes.Add(4, tvwChild, , "Cnode2")
Set gnode = TreeView1.Nodes.Add(5, tvwChild, , "extra1")
Set gnode = TreeView1.Nodes.Add(6, tvwChild, , "extra2")
End Sub

Private Sub cmdSwap_Click()
node1 = <index_of_first_node_to_swap>
node2 = <index_of_second_node_to_swap>
swapnodes
End Sub

Public Sub swapnodes()

Set selnode = TreeView1.Nodes(node1)
tempname = selnode.Text
temptag = selnode.Tag
tempkey1 = selnode.Key
    Set newnode = TreeView1.Nodes(node2)
    With selnode
        .Text = newnode.Text
        newnode.Text = tempname
        .Tag = newnode.Tag
        newnode.Tag = temptag
        .Key = "" ' set to nothing to avoid duplicates
        tempkey2 = newnode.Key ' store newnode key and swap
        newnode.Key = tempkey1
        .Key = tempkey2
    End With
If selnode.Children > 0 And newnode.Children > 0 Then
    gcheck = 1
    transfer
Else
    If selnode.Children > 0 Then
      gcheck = 2: transfer
    Else
      If newnode.Children > 0 Then
        gcheck = 3: transfer
      End If
    End If
End If
     
Set TreeView1.SelectedItem = newnode
TreeView1.SetFocus
End Sub

Public Sub transfer()
Dim tempnode As Node

Select Case gcheck
   
   Case 1: 'both selnode and newnode contain children.
      Set tempnode = TreeView1.Nodes.Add _
      (newnode.Index, tvwChild, , "temp")
      While selnode.Children > 0
          Set selnode.Child.LastSibling.Parent = tempnode
      Wend
      While newnode.Children > 0
          Set newnode.Child.LastSibling.Parent = selnode
      Wend
      Set tempnode = TreeView1.Nodes(selnode.Child.LastSibling.Index)
      While tempnode.Children > 0
        Set tempnode.Child.LastSibling.Parent = newnode
      Wend
      TreeView1.Nodes.Remove (tempnode.Index)
   
  Case 2: 'only selected node contains children
    While selnode.Children > 0
        Set selnode.Child.LastSibling.Parent = newnode
    Wend
   
  Case 3: 'only node above/below selected node have children
    While newnode.Children > 0
        Set newnode.Child.LastSibling.Parent = selnode
    Wend

End Select
   
End Sub
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
xersoftAuthor Commented:
Wow... I did not really thing this would be this involved... Thanks a lot though I think this will help greatly!
0
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

jgvCommented:
no sweat. if you have any difficulties implementing it, post a comment to this question and i'll help out if i can.
0
Alan WardSenior Design EngineerCommented:
Im using this: Works with children also. The node is an object so it holds all the data.  You can assign THIS node and OTHER node based on index as well.

        Dim NextNode As TreeNode = oNode.NextNode
        Dim NextNodeIndex As Integer = oNode.NextNode.Index
        Dim ThisNode As TreeNode = oNode
        Dim ThisNodeIndex As Integer = oNode.Index

        Me.TreeViewGroup.Nodes.Remove(ThisNode)
        Me.TreeViewGroup.Nodes.Remove(NextNode)

        'Now re-insert the nodes in each others index location
        Me.TreeViewGroup.Nodes.Insert(NextNodeIndex, ThisNode)
        Me.TreeViewGroup.Nodes.Insert(ThisNodeIndex, NextNode)
0
Alan WardSenior Design EngineerCommented:
Sorry, posted that a little to quick, here is the correct version that works.
Private Sub MoveDOWNToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MoveDOWNToolStripMenuItem.Click
        Dim TreeRef As TreeView = ContextMenuStripGroup.SourceControl
        Dim oNode As TreeNode = TreeRef.SelectedNode
        If TreeRef.SelectedNode Is Nothing Then
            MsgBox("Nothing Selected to move !", MsgBoxStyle.Information)
            Exit Sub
        End If
        If oNode.NextNode Is Nothing Then
            'cant move down anymore
            Exit Sub
        End If

        Dim ThisNode As TreeNode = oNode
        Dim ThisNodeIndex As Integer = oNode.Index
        Dim NextNode As TreeNode = oNode.NextNode
        Dim NextNodeIndex As Integer = oNode.NextNode.Index

        Me.TreeViewGroup.Nodes.Remove(ThisNode)
        Me.TreeViewGroup.Nodes.Remove(NextNode)

        'Now re-insert the nodes in each others index location
        Me.TreeViewGroup.Nodes.Insert(ThisNodeIndex, NextNode)
        Me.TreeViewGroup.Nodes.Insert(NextNodeIndex, ThisNode)

        'Select the node that we originally clicked on
        Me.TreeViewGroup.SelectedNode = ThisNode
    End Sub

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.