DÉPLACER DES NODES DANS UN TREEVIEW

Mindiell Messages postés 558 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 5 septembre 2007 - 28 juin 2004 à 11:55
cs_gregori Messages postés 1 Date d'inscription mercredi 5 mars 2003 Statut Membre Dernière intervention 22 novembre 2006 - 22 nov. 2006 à 17:15
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/24083-deplacer-des-nodes-dans-un-treeview

cs_gregori Messages postés 1 Date d'inscription mercredi 5 mars 2003 Statut Membre Dernière intervention 22 novembre 2006
22 nov. 2006 à 17:15
J'aurais tendance à suivre les conseils de rebelzkikione, en utilisant le .parent ou .child; en effet ça évite d'effacer - recréer le node, et ça évite les manipulations de sous-nodes et sous-sous nodes, vu que les "descendants" vont suivre automatiquement le node parent.
Comme rebelzkikione l'a évoqué, le node déplacé se retrouve en haut juste sous le node parent, mais là une petite astuce permet de redescendre le node là où il faut grâce aux arguments .next et .previous.

Private Sub CommandButton1_Click() 'Bouton pour remonter le node d'un cran dans la liste
'(vers le haut)
Dim CurrentNode As Node
Set CurrentNode = TreeView1.SelectedItem
MoveNodeUp CurrentNode
TreeView1.SetFocus
End Sub

Private Sub CommandButton2_Click() 'Bouton pour descendre le node d'un cran dans la liste
'(vers le bas)
Dim CurrentNode As Node
Set CurrentNode = TreeView1.SelectedItem
If (Not CurrentNode.Next Is Nothing) Then MoveNodeUp CurrentNode.Next
TreeView1.SetFocus
End Sub

Private Sub CommandButton3_Click() 'Bouton pour remonter le node d'un cran dans la hiérarchie
'(vers la gauche)
Dim CurrentNode As Node
Dim ParentNode As Node
Set CurrentNode = TreeView1.SelectedItem
Set ParentNode = CurrentNode.Parent
If ParentNode Is Nothing Then
TreeView1.SetFocus
Exit Sub
End If
If (Not ParentNode.Parent Is Nothing) Then
Set CurrentNode.Parent = ParentNode.Parent
Do
MoveNodeUp CurrentNode.Next
Loop Until CurrentNode.Previous.Key = ParentNode.Key
End If
TreeView1.SetFocus
End Sub

Private Sub CommandButton4_Click() 'Bouton pour descendre le node d'un cran dans la hiérarchie
'(vers la droite)
Dim CurrentNode As Node
Dim PreviousNode As Node
Set CurrentNode = TreeView1.SelectedItem
If (Not TreeView1.SelectedItem.Previous Is Nothing) Then
Set PreviousNode = CurrentNode.Previous
Set CurrentNode.Parent = PreviousNode
Do While Not CurrentNode.Next Is Nothing
MoveNodeUp CurrentNode.Next
Loop
End If
TreeView1.SetFocus
End Sub

Private Sub MoveNodeUp(CurrentNode As Node) 'Sub qui gère le remontage d'un cran dans la liste
Dim PreviousNode As Node
Set PreviousNode = CurrentNode.Previous
If CurrentNode.Parent Is Nothing Then Exit Sub
If CurrentNode.Parent.Children = 1 Or PreviousNode Is Nothing Then Exit Sub
Set CurrentNode.Parent = CurrentNode.Parent
Do
Set PreviousNode.Previous.Parent = PreviousNode.Previous.Parent
Loop Until PreviousNode.Previous.Key = CurrentNode.Key
End Sub

Toutefois pour des longues listes a mon avis il faudrait bloquer le rafraichissage de la fenêtre pendant le déplacement car ça doit "clignoter" (je n'ai pas essayé).

Greg
cs_mabrouklepoux Messages postés 84 Date d'inscription lundi 6 novembre 2000 Statut Membre Dernière intervention 25 juillet 2008 1
24 sept. 2006 à 00:03
bizarre...
pour déplacer un node
en théorie vous aves une structure arbo dans botre base
chaque élément possède un numéro correspondant à son père, ou -1 si c'est une racine.
donc, il suffit de mettre a jour ce numéro, et de réafficher l'arbre, non ?
DeadlyPredator Messages postés 222 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 30 juin 2008
29 juin 2004 à 18:31
J'aimerais vraiment savoir pourqoi dans le code modifié que je vous ai montrer un haut, la sous-sous node devient un sous node après un deuxième déplacement?
DeadlyPredator Messages postés 222 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 30 juin 2008
29 juin 2004 à 18:26
Je ne crois pas que utiliser un nom qui est aussi le nom d'une classe dérange car il faut créer un instance de la classe. C'est le seul cas où l'on peut utiliser un nom déjà existant je crois (il y a aussi le types). p.s. quand je développe, je veut tout déclarer d'avance par éviter des imprévus.
cs_Arknoth Messages postés 96 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 22 août 2004
29 juin 2004 à 17:18
Il aurait peut-être été intéressant d'avoir des bulles d'info en pointant les boutons, ca permettrai de mieux comprendre le fonctionnement.

Au Form_Load, tu aurais plutot du mettre une boucle For pour générer les nodes, avec la valeur Max en constante en début de projet.

Const cMaxNod = 8

For i = 1 To cMaxNod
.Add 1, tvwChild, , "noeudA" & CStr(i)
.Add 2, tvwChild, , "noeudB" & CStr(i)
EndFor

Autre chose :

Public Sub NodeMove(ByVal TreeView As TreeView

Esssaye d'éviter ce genre de déclaration où la variable est du nom de son type, ca provoque des erreurs

Sinon en effet, penche toi sur les fonctions, y a quelques bugs (notemment celui de faire d'un node enfant l'enfant d'un autre node, ca supprime le node enfant du premier)

A la rigueur, si tu t'en sens le courage, passe plutot par une fonction recursive, ca réduit le code au minimum et ca simplifie grandement le développement.

@pluche :p
rebelzkikione Messages postés 5 Date d'inscription mercredi 12 mars 2003 Statut Membre Dernière intervention 29 juin 2004
29 juin 2004 à 17:13
Hummm canard, sais - tu ke pour deplacer un node tu peux utiliser le .parent ? Le seul desavantage, c'est l'ordre du déplacement (le noeud deplacer devient le premier fils).

C'est bcp plus simple :) et ça te permettra d'utiliser le Tag(variant) de ton node pour mettre en relation une instance d'une classe... l'avantage c ke tu n'a po besoin de gerer destruction/creation d'un noeud ;)
DeadlyPredator Messages postés 222 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 30 juin 2008
28 juin 2004 à 23:05
J'ai réussi à permettre de déplacer aussi les sous-sous-nodes :
Public Sub NodeMove(ByVal TreeView As TreeView, ByVal SrcNode As Node, ByVal RefNode As Node, Optional ByVal RelationShip As NodeMoveType NodeMoveFirst, Optional ByVal SelectNode As Boolean True)
On Error Resume Next
Dim NewNode As Node, i As Long, j As Long, Children As Collection, SubChildren As SubChildrens, ChildrenNode As Node, SubChildrenNode As Node

If (SrcNode.Index RefNode.Index) And (RelationShip NodeMoveChild Or RelationShip = NodeMoveParent) Then Exit Sub 'LA NODE SE SUPPRIMERAIT...

Select Case RelationShip
Case 0 'NodeMoveChild
Set NewNode = TreeView.Nodes.Add(RefNode.Index, tvwChild)
Case 1 'NodeMoveParent
Set NewNode = TreeView.Nodes.Add(RefNode.Parent.Index, tvwNext)
Case 2 'NodeMoveFirst
Set NewNode = TreeView.Nodes.Add(RefNode.FirstSibling.Index, tvwFirst)
Case 3 'NodeMoveLast
Set NewNode = TreeView.Nodes.Add(RefNode.LastSibling.Index, tvwLast)
Case 4 'NodeMovePrevious
Set NewNode = TreeView.Nodes.Add(RefNode.Previous.Index, tvwPrevious)
Case 5 'NodeMoveNext
Set NewNode = TreeView.Nodes.Add(RefNode.Next.Index, tvwNext)
Case Else
Exit Sub
End Select

If Err.Number <> 0 Then Err.Clear: Exit Sub

With NewNode
.BackColor = SrcNode.BackColor
.Bold = SrcNode.Bold
.Checked = SrcNode.Checked
.Expanded = SrcNode.Expanded
.ExpandedImage = SrcNode.ExpandedImage
.ForeColor = SrcNode.ForeColor
.Image = SrcNode.Image
.Key = SrcNode.Key
.Sorted = SrcNode.Sorted
.SelectedImage = SrcNode.SelectedImage
.Tag = SrcNode.Tag
.Text = SrcNode.Text
End With

If SrcNode.Children <> 0 Then
'Save
Set Children = New Collection

For i = SrcNode.Child.Index To SrcNode.Child.Index + SrcNode.Children - 1
Set SubChildren = New SubChildrens
Set SubChildren.ParentNode = TreeView.Nodes.Item(i)
If SubChildren.ParentNode.Children <> 0 Then
For j = SubChildren.ParentNode.Child.Index To SubChildren.ParentNode.Child.Index + SubChildren.ParentNode.Children - 1
SubChildren.Children.Add TreeView.Nodes.Item(j)
Next
End If
Children.Add SubChildren
Set SubChildren = Nothing
Next
For i = 1 To Children.Count
Next
'\\'load
For i = 1 To Children.Count
Set ChildrenNode = TreeView.Nodes.Add(NewNode.Index, tvwChild)
With ChildrenNode
.BackColor = Children.Item(i).ParentNode.BackColor
.Bold = Children.Item(i).ParentNode.Bold
.Checked = Children.Item(i).ParentNode.Checked
.Expanded = Children.Item(i).ParentNode.Expanded
.ExpandedImage = Children.Item(i).ParentNode.ExpandedImage
.ForeColor = Children.Item(i).ParentNode.ForeColor
.Image = Children.Item(i).ParentNode.Image
.Key = Children.Item(i).ParentNode.Key
.Sorted = Children.Item(i).ParentNode.Sorted
.SelectedImage = Children.Item(i).ParentNode.SelectedImage
.Tag = Children.Item(i).ParentNode.Tag
.Text = Children.Item(i).ParentNode.Text
End With
For j = 1 To Children.Item(i).Children.Count
Set SubChildrenNode = TreeView.Nodes.Add(ChildrenNode.Index, tvwChild)
With SubChildrenNode
.BackColor = Children.Item(i).Children.Item(j).BackColor
.Bold = Children.Item(i).Children.Item(j).Bold
.Checked = Children.Item(i).Children.Item(j).Checked
.Expanded = Children.Item(i).Children.Item(j).Expanded
.ExpandedImage = Children.Item(i).Children.Item(j).ExpandedImage
.ForeColor = Children.Item(i).Children.Item(j).ForeColor
.Image = Children.Item(i).Children.Item(j).Image
.Key = Children.Item(i).Children.Item(j).Key
.Sorted = Children.Item(i).Children.Item(j).Sorted
.SelectedImage = Children.Item(i).Children.Item(j).SelectedImage
.Tag = Children.Item(i).Children.Item(j).Tag
.Text = Children.Item(i).Children.Item(j).Text
End With
Next
Set SubChildren = Nothing
Next

Set Children = Nothing
End If

TreeView.Nodes.Remove SrcNode.Index
If SelectNode True Then Set TreeView.SelectedItem NewNode

Set NewNode = Nothing
End Sub

Il faut par contre ajouter la classe SubChildrens :
Option Explicit

Public ParentNode As Node
Public Children As New Collection

Mais il y a encore un problème : quand on fait 1 déplacement, les sous-sous-nodes se copient comme il faut mais si on refait un autre déplacement avec la node, la sous-sous-node devient une sous-node.
DeadlyPredator Messages postés 222 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 30 juin 2008
28 juin 2004 à 19:46
Drag/Drop?Je sais qu'avec ça, on peut déclencher un évènement qui renvoit un x, y de la node vers laquelle l'utilisateur veut déposer une node mais je crois pas que ça permet de déplacer. Si je me trompe, dîtes-moi le.
Mindiell Messages postés 558 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 5 septembre 2007 1
28 juin 2004 à 11:55
Tu avais essaye le Drag'n'Drop pour voir ? :o)
Rejoignez-nous