Modify the order of a treeview control during runtime?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • dutsnekcirf
    New Member
    • Oct 2008
    • 10

    Modify the order of a treeview control during runtime?

    I have a treeview control on a custom task pane in Excel. I've enable the ability to use Drag & Drop (by following this how-to) on the treeview to change the order of the nodes. The problem though is if I close the application and then go back in, the nodes are back in the order they were before I had reordered them. Is there a way that I can modify my DragDrop event to permanently change the index of the nodes?

    Here's my code if you're interested. It's almost literally a copy and paste job from the site that I linked to above:

    Code:
    Private Sub ManningFiltersTreeView_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ManningFiltersTreeView.DragDrop
    
            'Check that there is a TreeNode being dragged
            If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
                  True) = False Then Exit Sub
    
            'Get the TreeView raising the event (incase multiple on form)
            Dim selectedTreeview As TreeView = CType(sender, TreeView)
    
            'Get the TreeNode being dragged
            Dim dropNode As TreeNode = _
                  CType(e.Data.GetData("System.Windows.Forms.TreeNode"),  _
                  TreeNode)
    
            'The target node should be selected from the DragOver event
            Dim targetNode As TreeNode = selectedTreeview.SelectedNode
    
            'Remove the drop node from its current location
            dropNode.Remove()
    
            'If there is no targetNode add dropNode to the bottom of
            'the TreeView root nodes, otherwise add it to the end of
            'the dropNode child nodes
            If targetNode Is Nothing Then
                selectedTreeview.Nodes.Add(dropNode)
            Else
                targetNode.Nodes.Add(dropNode)
            End If
    
            'Ensure the newly created node is visible to
            'the user and select it
            dropNode.EnsureVisible()
            selectedTreeview.SelectedNode = dropNode
    
        End Sub
    
        Private Sub ManningFiltersTreeView_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ManningFiltersTreeView.DragEnter
    
            'See if there is a TreeNode being dragged
            If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
                True) Then
                'TreeNode found allow move effect
                e.Effect = DragDropEffects.Move
            Else
                'No TreeNode found, prevent move
                e.Effect = DragDropEffects.None
            End If
    
        End Sub
    
        Private Sub ManningFiltersTreeView_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ManningFiltersTreeView.DragOver
    
            'Check that there is a TreeNode being dragged 
            If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
                   True) = False Then Exit Sub
    
            'Get the TreeView raising the event (incase multiple on form)
            Dim selectedTreeview As TreeView = CType(sender, TreeView)
    
            'As the mouse moves over nodes, provide feedback to 
            'the user by highlighting the node that is the 
            'current drop target
            Dim pt As Point = _
                CType(sender, TreeView).PointToClient(New Point(e.X, e.Y))
            Dim targetNode As TreeNode = selectedTreeview.GetNodeAt(pt)
    
            'See if the targetNode is currently selected, 
            'if so no need to validate again
            If Not (selectedTreeview.SelectedNode Is targetNode) Then
                'Select the    node currently under the cursor
                selectedTreeview.SelectedNode = targetNode
    
                'Check that the selected node is not the dropNode and
                'also that it is not a child of the dropNode and 
                'therefore an invalid target
                Dim dropNode As TreeNode = _
                    CType(e.Data.GetData("System.Windows.Forms.TreeNode"),  _
                    TreeNode)
    
                Do Until targetNode Is Nothing
                    If targetNode Is dropNode Then
                        e.Effect = DragDropEffects.None
                        Exit Sub
                    End If
                    targetNode = targetNode.Parent
                Loop
            End If
    
            'Currently selected node is a suitable target
            e.Effect = DragDropEffects.Move
            'End If
    
        End Sub
    
        Private Sub ManningFiltersTreeView_ItemDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemDragEventArgs) Handles ManningFiltersTreeView.ItemDrag
    
            'Set the drag node and initiate the DragDrop 
            DoDragDrop(e.Item, DragDropEffects.Move)
    
        End Sub
  • dutsnekcirf
    New Member
    • Oct 2008
    • 10

    #2
    I received a response in a different forum. I wanted to include it here because I'm hoping someone might be able to help me implement the solution. The response was:

    You'd need to save the status when the control is removed from memory, then restore it in the code that's initializing the control (when the task pane is being displayed the first time).

    The better place to ask this kind of question would be a forum that specializes in working with Windows Forms and their controls. The specialists there should be able to tell you the most efficient way to save the state of the control, then restore it at a later point.
    So if I understand this correctly, I need to save the status of the treeview control by writing it to a file (or another spreadsheet? (yes, this is in Excel using Visual Studio Tools for Office) before closing the workbook and then when the workbook is reopened it needs to read that data back into the control to display it's last state? Could this be done by databinding the treeview control to an Excel table? or would it be better to use some sort of XML file to better represent the heirarchy of the treeview control?

    Does anyone have any idea how to do this?

    Comment

    • dutsnekcirf
      New Member
      • Oct 2008
      • 10

      #3
      Okay, here's an idea everyone. What if on the thisworkbook_sh utdown event, I looped through the tree and extracted the text and fullpath properties of each node and added them to a Text and Path array and then wrote both arrays to a blank worksheet.

      And then as part of the thisworkbook_st artup event, I read through the range on my blank worksheet and added a node to the treeview and assigned each new node the fullpath property.

      So far I've got it working to write the status of my treeview to the spreadsheet. Here's the code that I'm using up to this point:


      Code:
              Dim Text As New List(Of String)
              Dim Path As New List(Of String)
      
              'Call the ExtractTextFromNodes function.  This finds all the text and fullpath properties of each node in the treeview and adds them to
              'a an array.
              ExtractTextFromNodes(APPredator.ManningFiltersTreeView.Nodes, Text, Path)
      
      
              Dim int As Integer = 0
      
              For i = 1 To Text.Count
                  CType(Globals.ThisWorkbook.Sheets("Manning Config"), Excel.Worksheet).Range("BV" & i).Value2 = Text(int)
                  int = int + 1
              Next
      
              int = 0
              For i = 1 To Path.Count
                  CType(Globals.ThisWorkbook.Sheets("Manning Config"), Excel.Worksheet).Range("BW" & i).Value2 = Path(int)
                  int = int + 1
              Next
      
      Private Shared Sub ExtractTextFromNodes(ByVal nodeList As TreeNodeCollection, ByVal Text As List(Of String), ByVal Path As List(Of String))
      
              Dim n As TreeNode
      
              For Each n In nodeList
      
      
                  Text.Add(n.Text)
                  Path.Add(n.FullPath)
                  ExtractTextFromNodes(n.Nodes, Text, Path)
      
      
              Next
      
          End Sub
      Next step is to read the data from my spreadsheet and build a treeview from it. If I've gone off track with this idea, let me know. If there's an easier way to do it, let me know too. :)

      Comment

      • dutsnekcirf
        New Member
        • Oct 2008
        • 10

        #4
        I've got this working now. The solution is found here .

        Comment

        Working...