Déplacer des nodes dans un treeview

Soyez le premier à donner votre avis sur cette source.

Vue 17 842 fois - Téléchargée 1 027 fois

Description

Ce petit bout de code permet de déplacer les nodes à l'intérieur d'un Treeview. J'ai réalisé ce code car j'en avait besoins... je désire donc le partager avec vous. Évidement, si jamais il y a une autre méthode plus "officielle", dîtes-moi le.

LIMITE :
Les sous-nodes des nodes déplacées sont transférées mais pas les sous-nodes de sous-nodes des nodes à tranférer.

Source / Exemple :


'/--------------------------------------------------'|>>Fait Par DeadlyPredator, Lundi le 27 Juin 2004<<|
'\--------------------------------------------------/
Public Enum NodeMoveType
NodeMoveChild = 0
NodeMoveParent = 1
NodeMoveFirst = 2
NodeMoveLast = 3
NodeMovePrevious = 4
NodeMoveNext = 5
End Enum
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, Children As Collection

    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

Set Children = New Collection

    For i = SrcNode.Child.Index To SrcNode.Child.Index + SrcNode.Children - 1
    Children.Add TreeView.Nodes.Item(i)
    Next
    
TreeView.Nodes.Remove SrcNode.Index

    For i = 1 To Children.Count
    NodeMove TreeView, Children.Item(i), NewNode, NodeMoveChild, False
    Next
    
Set Children = Nothing

Else

TreeView.Nodes.Remove SrcNode.Index

End If

If SelectNode = True Then Set TreeView.SelectedItem = NewNode

Set NewNode = Nothing
End Sub

Conclusion :


Un peu complexe quand même. Avec ça, on voit la base des TreeViews aussi.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1
Date d'inscription
mercredi 5 mars 2003
Statut
Membre
Dernière intervention
22 novembre 2006

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
Messages postés
84
Date d'inscription
lundi 6 novembre 2000
Statut
Membre
Dernière intervention
25 juillet 2008

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 ?
Messages postés
222
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
30 juin 2008

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?
Messages postés
222
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
30 juin 2008

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.
Messages postés
96
Date d'inscription
jeudi 2 janvier 2003
Statut
Membre
Dernière intervention
22 août 2004

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
Afficher les 9 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.