CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Jun 2011
    Posts
    14

    Moving/Swapping values in a TREEVIEW

    I appologize if this is a duplicate, but I could not find my first post.
    =====================
    Hello All:
    I just realized this section of the forum is available.

    I have a problem with some existing source code. I think I can tell you the lines that need to be modified, I just don't understand this enough to be able to make the change.

    Some fine folks here have helped me get this far, but I just can't get over this hump.

    I have attached the current project and associated source code, along with printscreens.

    Here is a summary of the problem.
    1)Run the project
    2)Select 'Load Tree'
    3)Select 'Sort'
    4)Look at Tv1 this is where the information is sorted and redisplayed.
    5)Everything NODE ending with an "*" should be sorted to the bottom of the tree, ALONG WITH everything under it.

    This is where my problem comes in. The second level is sorted to the end, but not the values underneath it.

    It is my understanding that when a node is moved/swapped everything under it will go with it. That is children stay with their parent. If it were working that way, my problem would be solved. However this code is moving the parent and leaving the children behind.

    I believe the problem is in the SortChild Sub and in the following lines, but I can't be sure

    Code:
                    Set chTemp = ch1(intI)
                    Set ch1(intI) = ch1(intRnd)
                    Set ch1(intRnd) = chTemp
    BEFORE SORT
    Name:  BEFORE.png
Views: 946
Size:  12.7 KB

    AFTER SORT
    Name:  AFTER.png
Views: 953
Size:  13.8 KB

    Should be:
    Name:  should.png
Views: 947
Size:  17.3 KB
    Attached Files Attached Files

  2. #2
    Join Date
    Jul 2005
    Posts
    1,083

    Re: Moving/Swapping values in a TREEVIEW

    It is my understanding that when a node is moved/swapped everything under it will go with it. That is children stay with their parent. If it were working that way, my problem would be solved. However this code is moving the parent and leaving the children behind.
    No, you should change the 'parent' in every child to the new parent key
    Post the code
    JG


    ... If your problem is fixed don't forget to mark your threads as resolved using the Thread Tools menu ...

  3. #3
    Join Date
    Jun 2011
    Posts
    14

    Re: Moving/Swapping values in a TREEVIEW

    jggtz,
    Thanks for the response.

    I have been having PC problems and just now getting back online.

    Here is the code.

    I have also included a zip file with the project and images of what the output should look like, along with an input file.

    If anyone can help with this, it is greatly appreciated. I have been battling this issue for over 2 months now.

    Thanks in advance.

    Code:
    Option Explicit
    Private Declare Function CoCreateGuid Lib "ole32.dll" (pGUID As Any) As Long
    
    Public Function CreateGUID() As String
        Dim i As Long, b(0 To 15) As Byte
        If CoCreateGuid(b(0)) = 0 Then
            For i = 0 To 15
                CreateGUID = CreateGUID & Right$("00" & Hex$(b(i)), 2)
            Next i
        Else
            MsgBox "Error While creating GUID!"
        End If
    End Function
    
    Private Function SetSecondElement(ByRef strS() As String) As Integer
    Dim intI As Integer
    intI = 1
    If UBound(strS) > 0 Then
        Do Until strS(intI) <> vbNullString
            intI = intI + 1
        Loop
        strS(1) = strS(intI)
    End If
    SetSecondElement = UBound(strS)
    End Function
    
    Private Sub Shuffle(strData() As String)
    '
    'Expects an array of values such as :
    'AA 111111
    'AB 222222
    'AC 333333
    'AD 444444
    ' and randomly 'shuffles' the numeric part
    ' to give, for example
    'AA 333333
    'AB 222222
    'AC 444444
    'AD 111111
    '
    ' When complete, strData will contain the 'shuffled' data
    ' (Assumes there's a 'Randomize' statement in the Form Load event)
    '
    Dim strResult() As String
    Dim strTemp As String
    Dim intI As Integer
    Dim intJ As Integer
    Dim intOL As Integer
    Dim intOL1 As Integer
    Dim intRnd As Integer
    Dim strS() As String
    Dim strS1() As String
    For intI = 0 To UBound(strData)
        '
        ' Create a Random number within the bounds of the Array
        '
        intRnd = Int(Rnd * (UBound(strData) + 1))
        '
        ' Form 2 parts of the current element's original data
        ' strS(0) = letters part
        ' rstS(1) = numeric part
        '
        'Debug.Print strData(intI)
        'Debug.Print strData(intRnd)
        strS = Split(strData(intI), " ")
        intOL = SetSecondElement(strS)
        '
        ' Save this element's numeric part
        '
        strTemp = strS(1)
        '
        ' Create a pair of parts for the Random element
        '
        strS1 = Split(strData(intRnd), " ")
        intOL1 = SetSecondElement(strS1)
        '
        ' Swap the numeric values
        '
        strS(1) = strS1(1)
        strS1(1) = strTemp
        '
        ' Put the modified values back into the original array
        '
        For intJ = 2 To UBound(strS)
            strS(intJ) = vbNullString
        Next intJ
        For intJ = 2 To UBound(strS1)
            strS1(intJ) = vbNullString
        Next intJ
        strData(intI) = strS(0) & Space(intOL) & strS(1)
        strData(intRnd) = strS1(0) & Space(intOL1) & strS1(1)
    Next intI
    End Sub
    
    Private Function GetLevel(strData As String) As Integer
    Dim intI As Integer
    intI = 1
    Do Until Mid$(strData, intI, 1) <> vbTab
        intI = intI + 1
    Loop
    GetLevel = intI - 1
    End Function
    
    Private Sub cmd_LoadTree_Click()
    LoadNodesFromFileWithTab
    End Sub
    
    Private Sub Cmd_Shuffle_Click()
    LoadNodesFromFileWithTab
    End Sub
    
    Private Sub cmd1_Click()
    Call ProcessAllChildren(tv.Nodes(1), tv.Nodes(1))
    Call ShuffleChildren(tv.Nodes(1))
    End Sub
    
    Private Sub cmdSort_Click()
    Call ProcessAllNodes(tv.Nodes(1), tv.Nodes(1))
    Call SortChildren(tv.Nodes(1))
    End Sub
    
    Private Sub Command1_Click()
    TreeviewSortSpecial
    End Sub
    
    Private Sub Form_Load()
    Randomize
    End Sub
    
    Public Sub LoadNodesFromFileWithTab()
        Dim text_line As String
        Dim level As Integer
        Dim tree_nodes() As Node
        Dim num_nodes As Integer
        
        Dim iFreefile As Integer
        Dim Treefile As String
        iFreefile = FreeFile
        Treefile = App.Path & "\ASCII_TREE.txt"
        Open Treefile For Input As iFreefile
        Form1.tv.Nodes.Clear
        Form1.Tv1.Nodes.Clear
          
        Do While Not EOF(iFreefile)
            Line Input #iFreefile, text_line
            level = 1
            Do While Left$(text_line, 1) = vbTab
                level = level + 1
                text_line = Mid$(text_line, 2)
            Loop
            If level > num_nodes Then
                num_nodes = level
                ReDim Preserve tree_nodes(1 To num_nodes)
     
            End If
            If level = 1 Then
           
                Set tree_nodes(level) = Form1.tv.Nodes.Add(, , CreateGUID, text_line)
                
            Else
               
                Set tree_nodes(level) = Form1.tv.Nodes.Add(tree_nodes(level - 1), tvwChild, CreateGUID, text_line)
                
                If level = 2 Then ' Show level 2
                   tree_nodes(level).EnsureVisible
                End If
            End If
        Loop
        Close iFreefile
    
        Open Treefile For Input As iFreefile
        Form1.Tv1.Nodes.Clear
        
        Do While Not EOF(iFreefile)
            Line Input #iFreefile, text_line
            level = 1
            Do While Left$(text_line, 1) = vbTab
                level = level + 1
                text_line = Mid$(text_line, 2)
            Loop
            If level > num_nodes Then
                num_nodes = level
                ReDim Preserve tree_nodes(1 To num_nodes)
     
            End If
            If level = 1 Then
           
                Set tree_nodes(level) = Form1.Tv1.Nodes.Add(, , CreateGUID, text_line)
                
            Else
               
                Set tree_nodes(level) = Form1.Tv1.Nodes.Add(tree_nodes(level - 1), tvwChild, CreateGUID, text_line)
                
                If level = 2 Then ' Show level 2
                   tree_nodes(level).EnsureVisible
                End If
            End If
        Loop
    '    Form1.tv.Nodes.Item(1).EnsureVisible
        Close iFreefile
    End Sub
    
    Private Sub ProcessAllChildren(ThisNode As Node, PreviousNode As Node)
    Dim NextNode As Node
    Dim intI As Integer
    Set NextNode = ThisNode.Child
    For intI = 1 To ThisNode.Children
        If NextNode.Children > 0 Then
            Call ProcessAllChildren(NextNode, ThisNode)
            Call ShuffleChildren(NextNode)
            Set NextNode = NextNode.Next
        End If
    Next intI
    End Sub
    
    Private Sub ShuffleChildren(TheNode As Node)
    Dim ch As Node
    Dim strChildList() As String
    Dim intI As Integer
    Dim intChildren As Integer
    intChildren = TheNode.Children
    If intChildren > 0 Then
        ReDim strChildList(intChildren - 1)
        Set ch = TheNode.Child
        strChildList(0) = ch.Text
        For intI = 1 To intChildren - 1
            Set ch = ch.Next
            strChildList(intI) = ch.Text
        Next intI
        Shuffle strChildList
        Set ch = TheNode.Child
        For intI = 0 To UBound(strChildList)
            ch.Text = strChildList(intI)
            Set ch = ch.Next
        Next intI
    End If
    End Sub
    
    
    Private Sub ProcessAllNodes(ThisNode As Node, PreviousNode As Node)
    Dim NextNode As Node
    Dim intI As Integer
    Set NextNode = ThisNode.Child
    For intI = 1 To ThisNode.Children
        If NextNode.Children > 0 Then
            Call ProcessAllNodes(NextNode, ThisNode)
            Call SortChildren(NextNode)
            Set NextNode = NextNode.Next
        End If
    Next intI
    End Sub '''
    
    Private Sub SortChildren(TheNode As Node)
    Dim ch As Node
    Dim ch1() As Node
    Dim strChildList() As String
    Dim intI As Integer
    Dim intChildren As Integer
    intChildren = TheNode.Children
    If intChildren > 0 Then
        ReDim strChildList(intChildren - 1)
        ReDim ch1(intChildren - 1)
        Set ch = TheNode.Child
        Set ch1(0) = TheNode.Child
        strChildList(0) = ch.Text
        For intI = 1 To intChildren - 1
            Set ch = ch.Next
            Set ch1(intI) = ch.Next
            strChildList(intI) = ch.Text
        Next intI
        SortChild strChildList, ch1
        Set ch = TheNode.Child
        For intI = 0 To UBound(strChildList)
            ch.Text = strChildList(intI)
            Set ch = ch.Next
        Next intI
    End If
    End Sub '
    
    
    
    Private Sub SortChild(strData() As String, ch1() As Node)
    Dim strResult() As String
    Dim chTemp As Node
    Dim strTemp As String
    Dim boSwap As Boolean
    Dim intI As Integer
    Dim intJ As Integer
    Dim intOL As Integer
    Dim intOL1 As Integer
    Dim intRnd As Integer
    Dim strS() As String
    Dim strS1() As String
    For intI = 0 To UBound(strData) - 1
        boSwap = False
        If Mid$(strData(intI), Len(strData(intI)), 1) = "*" Then
            intJ = intI + 1
            Do
                If Mid$(strData(intJ), Len(strData(intJ)), 1) <> "*" Then
                    intRnd = intJ
                    strS = Split(strData(intI), " ")
                    intOL = SetSecondElement(strS)
                    strTemp = strS(1)
                    strS1 = Split(strData(intRnd), " ")
                    intOL1 = SetSecondElement(strS1)
                    strS(1) = strS1(1)
                    strS1(1) = strTemp
                    For intJ = 2 To UBound(strS)
                        strS(intJ) = vbNullString
                    Next intJ
                    For intJ = 2 To UBound(strS1)
                        strS1(intJ) = vbNullString
                    Next intJ
                    strData(intI) = strS(0) & Space(intOL) & strS(1)
                    strData(intRnd) = strS1(0) & Space(intOL1) & strS1(1)
    
    
     ' &&&&&
    '          ' The following code was an attempt to move the entire node... but it does not work.
    '          ' The following three lines basically don't work.
                    Set chTemp = ch1(intI)
                    Set ch1(intI) = ch1(intRnd)
                    Set ch1(intRnd) = chTemp
                    boSwap = True
                Else
                    intJ = intJ + 1
                End If
            Loop Until intJ > UBound(strData) Or boSwap = True
        End If
    Next intI
    End Sub
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured