Solved

how to change Treeview items order?

Posted on 1999-01-01
15
173 Views
Last Modified: 2010-05-03
How i can move, with a Drag&Drop, move an item AFTER or BEFORE another item, instead of IN or OUT?
(i.e. like the netscape bookmark manager)
0
Comment
Question by:parduz
  • 8
  • 3
  • 2
  • +2
15 Comments
 
LVL 1

Expert Comment

by:bear454
ID: 1453552
What do you mean, In and Out ?
0
 

Author Comment

by:parduz
ID: 1453553
I try to explain (i'm italian, so excuse my bad english)

This is the start situation:            This is what i need using dragging NodeC:

Root                                                       Root
  |                                                              |
 +----NodeA                                           +----NodeA
           |                                                              |
          +----NodeB                                            +----NodeC
           |                                                              |
           -----NodeC                                             -----NodeB
 
I'm not able to make this. With drag&drop, i only can put NodeC INSIDE NodeB, or OUTSIDE NodeA.

What i obtain now from the drag&drop op.:

Root                                                       Root
  |                                                              |
 +----NodeA                                           +----NodeA
  |         |                                                              |
  |         ----NodeB                                             ----NodeB
  |                                                                                |
   -----NodeC                                                             -----NodeC

.and i dont want this.
I hope you can understand me.
Fabio
0
 

Expert Comment

by:israelw
ID: 1453554
hi parduz!

here you have an answer to your question, but this sample is not perfectly with the visual interface like the drag image
but it's work and work good.

be well.
israel w.

Dim MoveNode As Node
Private Sub Form_Load()

    tree1.Nodes.Add , , "a", "Node A"
    tree1.Nodes.Add "a", 4, "b", "Node B"
    tree1.Nodes.Add "a", 4, "c", "Node C"
   
End Sub

Private Sub tree1_DragDrop(Source As Control, x As Single, y As Single)
Dim DestNode As Node

    If Source.Name = "tree1" Then
        If tree1.DropHighlight Is Nothing Then
            tree1.DropHighlight = Nothing
            Exit Sub
        ElseIf tree1.DropHighlight Is MoveNode Then
            tree1.DropHighlight = Nothing
            Exit Sub
        ElseIf tree1.DropHighlight.Children = 0 Then
            Set DestNode = tree1.DropHighlight
            Key = MoveNode.Key
            tree1.Nodes.Add DestNode.Index, tvwPrevious, , MoveNode.Text
            tree1.Nodes.Remove MoveNode.Index
            DestNode.Previous.Key = Key
        End If
    End If
End Sub

Private Sub tree1_DragOver(Source As Control, x As Single, y As Single, State As Integer)
    If Not tree1.HitTest(x, y) Is MoveNode Then
        Set tree1.DropHighlight = tree1.HitTest(x, y)
    End If
End Sub

Private Sub tree1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    Set MoveNode = tree1.SelectedItem
    If Button = 1 And tree1.SelectedItem.Children = 0 Then
        tree1.DragIcon = tree1.SelectedItem.CreateDragImage
        tree1.Drag vbBeginDrag
    End If
End Sub

0
 

Author Comment

by:parduz
ID: 1453555
Hi Israelw!
SORRY FOR THE LONG TIME! MY WORK IS A NIGHTMARE!
The fault is mine.
In the method proposed, i can ONLY make the "move" node, but now i cannot put inside another node.
YES, reading my question i that i want, i know my english is poor.
Is for this reason i say "like escape bookmark manager", is the only way i have to try to explain.
So, we can make this:
If you can solve the entire question , i give you the 200 points.
If someone else solve the problem, i give you 100 points, and 100 points to the solver.
Do you think this is right?
Sorry again for my mistake!!
0
 
LVL 12

Expert Comment

by:jgv
ID: 1453556
I have a small program I wrote for someone with a similar problem. It will exchange the selected node's position with the node above or below it. The limitation is that you can only move a node among it's own siblings. I can email the app if you want to have a look at it :o)
0
 

Author Comment

by:parduz
ID: 1453557
For jgv:
Sure! (and Thanks!)
How we can exchange e-mail address with "privacy"?
0
 
LVL 7

Expert Comment

by:Inteqam
ID: 1453558
lol

put your email address so he can send you his.
lol

0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 

Author Comment

by:parduz
ID: 1453559
OK
parduz@mail.asianet.it
0
 
LVL 12

Expert Comment

by:jgv
ID: 1453560
Not what you were looking for?
0
 

Author Comment

by:parduz
ID: 1453561
Sorry, my job eating now all my time.   :-(
i put a comment here when i can evalute your sample.
Sorry again!

0
 

Expert Comment

by:israelw
ID: 1453562
hi parduz!

it's a comeback.

ho... you can to clearly and easily make the change you need to accomplish your needs.

you just have to add another if condition to the code i given you before.

it's have to be sothing like this:

you remember i ask in the code

      ElseIf tree1.DropHighlight Is MoveNode Then
           tree1.DropHighlight = Nothing
           Exit Sub

you can put here this code:
      ElseIf tree1.DropHighlight.Children >0 and _
             tree1.DropHighlight <> MoveNode.patrent  Then
                   Set DestNode = tree1.DropHighlight
                   Key = MoveNode.Key
                   tree1.Nodes.Add DestNode.Index, tvwchild, ,                                    MoveNode.Text
                   tree1.Nodes.Remove MoveNode.Index
                   DestNode.Previous.Key = Key

i hope you can understand this solution if not just ask.

0
 

Author Comment

by:parduz
ID: 1453563
I'M BACK (AND FREE!)

1) My excuses:
I know that is too much time i'm "mute" about this question:
my work force me to travel between Hannover ans Casablanca for all this time!
If you have seen other questions posed by me on this site, is why are related to the job i was making. Now this hell is terminated, and i can live with my familly, in my house, and with my "Experts-exchange" friends (if you agree this term).

2) This question:
I've a problem: i can solve this question mixing the answer of israelw (that have some bugs and need more code to work properly) with the jgv's  project (send to me by E-Mail) that works better moving nodes but dont use Drag&Drop.
For justice, i think i must give 100pts each, but this is my idea and i dont know what you think about this.
More, in this question i like to put the code resulting by this "mix".
More again, i want "pay" the time you waits some notice by me.
So this is my purpose:
1) I send to jgv (i choice him because i've the e-mail,not for others reasons) the working code (when finished).
2) jgv put here my code as an answer.
3) I accept the answer with a Good for the 200 points,
4) I create an empty question for israelw for 200 pts,
5) israelw answer the question and gain pts.
6) I offer at jgv and israelw a drink (How?)

Put here a comment about this trip.
parduz
0
 

Author Comment

by:parduz
ID: 1453564
Ok, a new update.
jgv send me by email an almost fully functional project. I've modified some code, but the right answer is from jgv.
I heave send to him the finished code, so he can put here the fully functional code as answer.
Do notput here other answer, i accept only the jgv code.
Thanks to all.
parduz
0
 
LVL 12

Accepted Solution

by:
jgv earned 200 total points
ID: 1453565
As per parduz's request:

Option Explicit

    ' Icons i use during DragDrop
    Dim PlaceBoth As String
    Dim PlaceNone As String
    Dim PlaceUp As String
    Dim PlaceDown As String
    Dim PlaceChild As String
   
    ' The Source node
    Dim DraggedNode As Node

    ' Where i want to put the source
    Enum MoveDirection
        moveup = 0
        movedown = 1
        moveinside = 2
    End Enum
    Dim MoveDir As MoveDirection

Private Sub Form_Activate()

    Dim gnode As Node
   
    ' Set the icons path
    PlaceBoth = App.Path & "\Place Between.ico"
    PlaceNone = App.Path & "\Place none.ico"
    PlaceUp = App.Path & "\Place up.ico"
    PlaceDown = App.Path & "\Place down.ico"
    PlaceChild = App.Path & "\Place children.ico"

    With T1.Nodes
        Set gnode = .Add(, , "Root", "Root")
        Set gnode = .Add("Root", tvwChild, "NodeA", "NodeA")
        Set gnode = .Add("NodeA", tvwChild, "Anode1", "Anode1")
        Set gnode = .Add("NodeA", tvwChild, "Anode2", "Anode2")
        Set gnode = .Add("Anode1", tvwChild, "extra1", "extra1")
        gnode.EnsureVisible
        Set gnode = .Add("Anode2", tvwChild, "extra2", "extra2")
        gnode.EnsureVisible
        Set gnode = .Add("NodeA", tvwChild, "Anode3", "Anode3")
        gnode.EnsureVisible
        Set gnode = .Add("Root", tvwChild, "NodeB", "NodeB")
        Set gnode = .Add("Root", tvwChild, "NodeC", "NodeC")
        Set gnode = .Add("Root", tvwChild, "NodeD", "NodeD")
        Set gnode = .Add("Root", tvwChild, "NodeE", "NodeE")
        Set gnode = .Add("NodeB", tvwChild, "Bnode1", "Bnode1")
        gnode.EnsureVisible
        Set gnode = .Add("NodeB", tvwChild, "Bnode2", "Bnode2")
        gnode.EnsureVisible
        Set gnode = .Add("NodeC", tvwChild, "Cnode1", "Cnode1")
        gnode.EnsureVisible
        Set gnode = .Add("NodeC", tvwChild, "Cnode2", "Cnode2")
        gnode.EnsureVisible
           
    End With

End Sub

Private Sub T1_DragOver(Source As Control, X As Single, Y As Single, State As Integer)
   
    ' A bunch of new code: i need to proper _
      move the node up or down the "destination" _
      node, not only up. More, i want also put the _
      "dragged" node as a child. So, the solution is _
      use X and Y to see in what position i'm inside _
      the "destination" node:
      ' If i'm in the middle, i put the source as child, _
       if i'm near to top i put the source Up, _
       if i'm near to bottom i put the source down.
     
    ' this is only to simplify the Select Case routine (see below)
    Dim Result As Integer
   
    ' The node i search Up the HitTest
    Dim UpNode As Node
    ' The node i search Down the HitTest
    Dim DwNode As Node
    ' The node i get by HitTest
    Dim HiNode As Node
   
    Set T1.DropHighlight = T1.HitTest(X, Y)
    Set HiNode = T1.DropHighlight
    Set UpNode = T1.HitTest(X, Y - 40)
    Set DwNode = T1.HitTest(X, Y + 40)
   
    ' Make a Select Case with all combination of this conditions is _
      a nightmare. Using this solution make code more simple: _
      I use bits to store the results of the HitTests, so the Result _
      have unique values. It's hard to explain for me, i hope you _
      can understand.
    Result = 0
    If HiNode Is Nothing Then Result = Result + 1 ' = 0001
    If UpNode Is Nothing Then Result = Result + 2  ' = 0010
    If DwNode Is Nothing Then Result = Result + 4 ' = 0100
   
    If Not HiNode Is Nothing Then
        ' If the Destination node is also the source:
        If HiNode = DraggedNode Then Result = 7
        ' If the Destination node is the parent of source:
        If HiNode = DraggedNode.Parent Then Result = 7
    End If
    Select Case Result
       
        Case 0 ' all nodes are ok
             
             If HiNode = UpNode And HiNode = DwNode Then
                ' i'm in center of highlighted node
                T1.DragIcon = LoadPicture(PlaceChild)
                MoveDir = moveinside
             ElseIf HiNode = UpNode Then
                ' I'm "between" two nodes
                T1.DragIcon = LoadPicture(PlaceBoth)
                MoveDir = movedown
             
             ElseIf HiNode = DwNode Then
                ' I'm "between" two nodes
                T1.DragIcon = LoadPicture(PlaceBoth)
                MoveDir = moveup
             Else
                ' How i can be here?
                Beep
                Stop
            End If
       
        Case 1 ' i'm over nothing but up and down are ok (is it possible?)
            ' How i can be here?
            Beep
            Stop
       
        Case 2 ' the node up is nothing
            T1.DragIcon = LoadPicture(PlaceUp)
            MoveDir = moveup
        Case 3 ' only the node down is good
            If DwNode = DraggedNode Then
                T1.DragIcon = LoadPicture(PlaceNone)
                Set T1.DropHighlight = Nothing
            Else
                Set T1.DropHighlight = DwNode
                T1.DragIcon = LoadPicture(PlaceUp)
                MoveDir = moveup
            End If
        Case 4 ' the node down is nothing
            T1.DragIcon = LoadPicture(PlaceDown)
            MoveDir = movedown
        Case 5 ' only the node up is good
            If UpNode = DraggedNode Then
                T1.DragIcon = LoadPicture(PlaceNone)
                Set T1.DropHighlight = Nothing
            Else
                Set T1.DropHighlight = UpNode
                T1.DragIcon = LoadPicture(PlaceDown)
                MoveDir = movedown
            End If
        Case 6 ' no up or down nodes (another impossible condition?)
            T1.DragIcon = LoadPicture(PlaceChild)
            MoveDir = moveinside
        Case 7 ' no one node is good
            T1.DragIcon = LoadPicture(PlaceNone)
            Set T1.DropHighlight = Nothing
    End Select
   
    Set UpNode = Nothing
    Set DwNode = Nothing
    Set HiNode = Nothing
   
End Sub

Private Sub T1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

    Set T1.SelectedItem = T1.HitTest(X, Y)
    Set DraggedNode = T1.SelectedItem
    Set T1.DropHighlight = Nothing

End Sub

Private Sub T1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)

    If Button = vbLeftButton Then
        'T1.DragIcon = LoadPicture(SwapBoth)
        T1.Drag vbBeginDrag
    End If

End Sub

Private Sub T1_DragDrop(Source As Control, X As Single, Y As Single)
   
    On Error GoTo CheckError
   
    Dim Target As Node

    If T1.DropHighlight Is Nothing Then
        Source.Drag vbEndDrag
        Set DraggedNode = Nothing
        Exit Sub
    End If
   
    Set Target = T1.DropHighlight
'***************************************************
'The swapnodes sub, and the following bit
'of code does all the work.
'***************************************************
   
    'keep swapping nodes until the dragged/dropped node is above
    'the target node.
    Select Case MoveDir
        Case moveinside
            Set DraggedNode.Parent = Target
       
        Case moveup
            SwapNodes Target
       
        Case movedown
            ' To put the source after (down) destination, i create a "fake" destination
            ' after the real destination.
            Set Target = T1.Nodes.Add(Target.Index, tvwNext, "temp", "temp")
            SwapNodes Target
            ' Now i can remove the fake destination
            T1.Nodes.Remove "temp"
    End Select
'***************************************************
'***************************************************
ExitOfSub:

    Set T1.DropHighlight = Nothing
    Set Target = Nothing
    Set DraggedNode = Nothing
   
    Exit Sub

CheckError:
    'if a parent node is dropped on one of it's child nodes a
    'circularerror is raised.
    If Err.Number = 35614 Then Set T1.DropHighlight = Nothing
    MsgBox Err.Number & " " & Err.Description
    Resume ExitOfSub
End Sub

Private Sub SwapNodes(ByVal Target As Node)
   
    ' This is ALL: i follow your idea, but seems exist a simple way
    ' to do the job:
    ' I swap all nodes (related to Source.parent) until Source is before (up) the Destination
    Dim Swapped As Node
           
    Set DraggedNode.Parent = Target.Parent
    Do Until Target.Previous = DraggedNode
        Set Swapped = Target.Previous
        Set Swapped.Parent = Target.Parent
    Loop
    Set Swapped = Nothing
End Sub
0
 

Author Comment

by:parduz
ID: 1453566
All right, this is the answer!
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
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…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

747 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now