Mindiell
Messages postés558Date d'inscriptionjeudi 25 juillet 2002StatutMembreDernière intervention 5 septembre 2007
-
28 juin 2004 à 11:55
cs_gregori
Messages postés1Date d'inscriptionmercredi 5 mars 2003StatutMembreDernière intervention22 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.
cs_gregori
Messages postés1Date d'inscriptionmercredi 5 mars 2003StatutMembreDernière intervention22 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és84Date d'inscriptionlundi 6 novembre 2000StatutMembreDernière intervention25 juillet 20081 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és222Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention30 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és222Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention30 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és96Date d'inscriptionjeudi 2 janvier 2003StatutMembreDernière intervention22 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és5Date d'inscriptionmercredi 12 mars 2003StatutMembreDernière intervention29 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és222Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention30 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 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és222Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention30 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és558Date d'inscriptionjeudi 25 juillet 2002StatutMembreDernière intervention 5 septembre 20071 28 juin 2004 à 11:55
22 nov. 2006 à 17:15
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
24 sept. 2006 à 00:03
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 ?
29 juin 2004 à 18:31
29 juin 2004 à 18:26
29 juin 2004 à 17:18
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
29 juin 2004 à 17:13
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 ;)
28 juin 2004 à 23:05
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.
28 juin 2004 à 19:46
28 juin 2004 à 11:55