IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

TreeView et Récursivité


Sujet :

VB.NET

  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2011
    Messages : 70
    Par défaut TreeView et Récursivité
    Bonjour,

    Je dois créer un programme permettant la visualisation d'associations entre deux TreeView remplis dynamiquement.
    Pour cela, il me faut donc parcourir chacun des noeuds d'un TreeView et vérifier si il correspond au résultat de la requête, pour cela, je maîtrise la bonne méthode bien horrible et extrêmement peu fonctionnelle de l'imbrication en masse de For To Next...

    Comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    If oDataReader.HasRows Then
                    Do While oDataReader.Read()
                        Dim strTemp As String = oDataReader("num_classification")
     
                        For i As Integer = 0 To Me.tvClassification.GetNodeCount(False) - 1
                            If String.Compare(Me.tvClassification.Nodes(i).Name, strTemp) = 0 Then
                                Me.tvClassification.Nodes(i).Expand()
                                Me.tvClassification.Nodes(i).BackColor = Color.Red
                                Me.tvClassification.Nodes(i).ForeColor = Color.White
                            End If
     
                            For j As Integer = 0 To Me.tvClassification.Nodes(i).GetNodeCount(False) - 1
                                If String.Compare(Me.tvClassification.Nodes(i).Nodes(j).Name, strTemp) = 0 Then
                                    Me.tvClassification.Nodes(i).Expand()
                                    Me.tvClassification.Nodes(i).Nodes(j).Expand()
                                    Me.tvClassification.Nodes(i).Nodes(j).BackColor = Color.Red
                                    Me.tvClassification.Nodes(i).Nodes(j).ForeColor = Color.White
                                End If
     
                                For k As Integer = 0 To Me.tvClassification.Nodes(i).Nodes(j).GetNodeCount(False) - 1
                                    If String.Compare(Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Name, strTemp) = 0 Then
                                        Me.tvClassification.Nodes(i).Expand()
                                        Me.tvClassification.Nodes(i).Nodes(j).Expand()
                                        Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Expand()
                                        Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).BackColor = Color.Red
                                        Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).ForeColor = Color.White
                                    End If
     
                                    For l As Integer = 0 To Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).GetNodeCount(False) - 1
                                        If String.Compare(Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).Name, strTemp) = 0 Then
                                            Me.tvClassification.Nodes(i).Expand()
                                            Me.tvClassification.Nodes(i).Nodes(j).Expand()
                                            Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Expand()
                                            Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).Expand()
                                            Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).BackColor = Color.Red
                                            Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).ForeColor = Color.White
                                        End If
                                        For m As Integer = 0 To Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).GetNodeCount(False) - 1
                                            If String.Compare(Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).Nodes(m).Name, strTemp) = 0 Then
                                                Me.tvClassification.Nodes(i).Expand()
                                                Me.tvClassification.Nodes(i).Nodes(j).Expand()
                                                Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Expand()
                                                Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).Expand()
                                                Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).Nodes(m).Expand()
                                                Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).Nodes(m).BackColor = Color.Red
                                                Me.tvClassification.Nodes(i).Nodes(j).Nodes(k).Nodes(l).Nodes(m).ForeColor = Color.White
                                            End If
                                        Next
                                    Next
                                Next
                            Next
                        Next
                    Loop
                End If
    J'ai déjà dit trouver ça horriblement peu fonctionnel?

    J'aimerais remplacer ce code par des fonctions récursives du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
        Private Sub TestRecursive(ByVal tn As TreeNode, ByVal str As String)
            For Each tn In tn.Nodes
                If String.Compare(tn.Name, str) = 0 Then
                    tn.Expand()
                    tn.ForeColor = Color.White
                    tn.BackColor = Color.Red
                End If
            Next
        End Sub
        Private Sub CallTestRecursive(ByVal tv As TreeView, ByVal str As String)
            Dim n As TreeNode
            For Each n In tv.Nodes
                TestRecursive(n, str)
            Next
        End Sub
    Le code avec les "For" donne bien le résultat attendu, ce n'est pas le cas des mes fonctions récursives, je me demande donc d'ou peu venir le problème.
    J'ai déjà réussi à utiliser la récursivité pour réinitialiser la couleur de chaque noeud de mes TreeView, mais dans ce cas, je heurte un mur...

    Peut-être quelqu'un ayant mieux saisi ce concept de récursivité pourrait m'éclairer sur ce qui bloque mon avancée ?


    Ah, peut-être avez vous besoin de ma requête, je l'ajoute au cas où :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
                Dim strTmp As String = tvMenu.SelectedNode.Name 'Contient "num_classification"
                Dim strRequete As String = "SELECT id_mainmenu, id_section, id_sous_section, MC.id_classification, num_classification " & _
                                           "FROM menus_classifications AS MC " & _
                                                "RIGHT OUTER JOIN classifications AS C " & _
                                                "ON MC.id_classification = C.id_classification " & _
                                           "WHERE id_mainmenu = '" & strTmp & "' " & _
                                                "OR (id_section = '" & strTmp & "') " & _
                                                "OR (id_sous_section = '" & strTmp & "')"
                Dim oCmdSQL As New OleDbCommand(strRequete, oConnection)
     
                Dim oDataReader As OleDbDataReader = oCmdSQL.ExecuteReader
    Voilà, j'espère avoir fait preuve de clarté lors de mes explication, si certains points sont flou, je m'efforcerai d'éclaircir cela. Merci d'avacne à ceux qui auront le temps de m'aider

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 194
    Par défaut
    pour la récursivité il faudrait que TestRecursive appelle TestRecursive

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    For Each stn In tn.Nodes
      If String.Compare(stn.Name, str) = 0 Then
        stn.Expand()
        stn.ForeColor = Color.White
        stn.BackColor = Color.Red
      End If
      TestRecursive(stn, str)
    Next
    et puis évite d'avoir 2 variables du même nom dans une méthode

    sinon quand tu créés un noeud, tu peux l'ajouter à un list(of node)
    et ensuite boucler sur cette collection pour vérifier le name
    et peux importe ou se trouve le noeud tu pourras modifier dessus ou autre
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Par défaut
    Bonjour,

    Concernant votre "fonction récursive" en fait elle ne l'est pas, le principe de la récursivité (en version courte) c'est d'avoir une méthode qui se rappelle elle même.

    Pour être sûr de ne pas écrire d'ânerie, je me suis fait un petit projet de test, contenant un Treeview, un TextBox (pour saisir le texte à rechercher) et un Button.
    J'ai mis une arborescence factice dans mon treeview comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    + Root1
    |___ Node1_1
    |___ Node1_2
     
    + Root2
    |__+ Node2_1
    |    |___ Node2_1_1
    |    |___ Node2_1_2
    |__+ Node2_2
         |___ Node2_2_1
     
    + Root3
    |___ Node3_1
    Et voici le code que j'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        ' Lance la recherche sur le Treeview
        SearchTreeView(TreeView1, TextBox1.Text)
    End Sub
     
     
    Private Sub SearchTreeView(ByVal tv As TreeView, ByVal text As String)
        ' Pour chaque noeud du Treeview lancer la recherche sur ce noeud
        For Each tn As TreeNode In tv.Nodes
            SearchTreeNode(tn, text)
        Next
    End Sub
     
    Private Function SearchTreeNode(ByVal tn As TreeNode, ByVal text As String) As Boolean
        ' Sert à garder une trace de la découverte d'un sous-noeud
        ' correspondant à la recherche pour pouvoir "Expander" les antécédants
        Dim foundInChild As Boolean = False
     
        ' Pour chaque sous-noeud on rappelle la recherche 1 niveau en dessous (récursion)
        For Each subTn As TreeNode In tn.Nodes
            ' Si un sous-noeud a été trouvé (= si l'appel renvoie True)
            ' on place le bool a True aussi pour que les "Expand" remontent la hiérarchie
            If SearchTreeNode(subTn, text) Then foundInChild = True
        Next
     
        ' On traite le noeud actuel : S'il correspond à la recherche
        ' ou un de ses enfants y correspondait, on l'Expand
        If tn.Name = text OrElse foundInChild Then
            tn.Expand()
            foundInChild = True
        End If
     
        Return foundInChild
    End Function
    Voilà basiquement l'idée, après je n'ai pas géré les changements de couleurs mais ça ne devrait pas être trop dur à adapter je pense.

    Cordialement !

    Edit: en partie grillé par Pol63 (quelle idée d'écrire de tels pavés aussi)

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 194
    Par défaut
    Citation Envoyé par Sehnsucht Voir le message
    Edit: en partie grillé par Pol63 (quelle idée d'écrire de tels pavés aussi)

    y a une feinte pour par se faire griller, tu écris les 2 ou 3 lignes de base, tu postes, et tu édites pour rajouter le reste
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Treeview et récursivité
    Par diouki dans le forum C++Builder
    Réponses: 4
    Dernier message: 27/08/2013, 15h06
  2. Arborescence par récursivité - treeview
    Par Renaud976 dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 19/11/2011, 05h41
  3. TreeView et menu contextuel...
    Par agh dans le forum Composants VCL
    Réponses: 6
    Dernier message: 06/04/2009, 12h23
  4. où y a t il un tutorial pour le Treeview ??
    Par silvermoon dans le forum C++Builder
    Réponses: 4
    Dernier message: 09/12/2002, 13h30
  5. [Pointer]Treeview.Data
    Par rbag dans le forum Composants VCL
    Réponses: 7
    Dernier message: 31/08/2002, 01h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo