?
Solved

The treeview control. Changing order of nodes

Posted on 1999-11-23
6
Medium Priority
?
382 Views
Last Modified: 2013-12-25
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!
0
Comment
Question by:xersoft
  • 3
  • 2
6 Comments
 
LVL 12

Expert Comment

by:jgv
ID: 2230297
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
 
LVL 12

Accepted Solution

by:
jgv earned 800 total points
ID: 2231115
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
 
LVL 5

Author Comment

by:xersoft
ID: 2232252
Wow... I did not really thing this would be this involved... Thanks a lot though I think this will help greatly!
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
LVL 12

Expert Comment

by:jgv
ID: 2233196
no sweat. if you have any difficulties implementing it, post a comment to this question and i'll help out if i can.
0
 

Expert Comment

by:Alan Ward
ID: 33108581
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
 

Expert Comment

by:Alan Ward
ID: 33108631
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

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses

588 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question