FAQ VB.NETConsultez toutes les FAQ

Nombre d'auteurs : 36, nombre de questions : 239, dernière mise à jour : 24 mai 2015  Ajouter une question

 

Cette FAQ a été réalisée pour répondre aux questions les plus fréquemment posées sur le forum Développement DotNET

Je tiens à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle contient sont correctes. Les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci.

Sur ce, je vous souhaite une bonne lecture.


SommaireWinFormsTreeView (5)
précédent sommaire suivant
 

Ce code permet de charger l'arborescence du disque dur C:\ dans un TreeView de la même façon que l'Explorateur Windows.
Ce code nécessite un contrôle TreeView nommé TV et un Button nommé BTN.

Code vb.net : Sélectionner tout
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
Imports System 
Imports System.IO 
Imports System.Windows.Forms 
  
' ... 
  
Private Sub Explorer(ByVal node As TreeNode) 
    Try 
        Dim s As String 
        node.Nodes.Clear() 
        For Each s In Directory.GetDirectories(node.FullPath) 
            node.Nodes.Add(Path.GetFileName(s)) 
        Next 
    Catch 
    End Try 
End Sub 
  
Private Sub BTNClick(ByVal sender As Object, ByVal e As EventArgs) 
    TV.Nodes.Add("C:\") 
    Explorer(TV.Nodes.Item(0)) 
End Sub 
  
  
Private Sub TVAfterExpand(ByVal sender As Object, ByVal e As TreeViewEventArgs) 
    Dim tn As TreeNode 
    For Each tn In e.Node.Nodes 
        Explorer(tn) 
    Next 
End Sub

Mis à jour le 30 octobre 2013 HULK

La manipulation de l'arborescence peut être assez complexe si le concept de nœuds n'est pas correctement assimilé. En fait les objets TreeNodes qui composent un objet TreeView sont des collections récursives. Les règles suivantes s'appliquent toujours :

  • Il n'existe qu'un nœud 'Root'. On l'identifie par la valeur « Nothing » de son parent ;
  • Un nœud n'a toujours qu'un seul parent ;
  • Un nœud ne fournit des informations que sur ses descendants directs.

Comme il s'agit de collection récursive, le code suivant parcourt tous les nœuds enfants du nœud passé en paramètre :

Code vb.net : Sélectionner tout
1
2
3
4
5
6
7
Private Sub ParcoursNoeud(ByVal MonNode As TreeNode) 
    MsgBox(MonNode.ToString) 
    Dim MonEnum As IEnumerator = MonNode.Nodes.GetEnumerator 
    While MonEnum.MoveNext 
        ParcoursNoeud(CType(MonEnum.Current, TreeNode)) 
    End While 
End Sub
La position hiérarchique (parfois appelée niveau d'imbrication) n'est pas toujours simple à connaître. Pour la trouver, je peux utiliser une fonction récursive du type :

Code vb.net : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
Private Function Niveau(ByVal MonNode As TreeNode, ByVal Start As Boolean) As Int32 
    Static Pos As Int32 
    If Start Then Pos = 0 
    If MonNode.Parent Is Nothing Then 
        Return Pos 
    Else 
        Pos += 1 
        Niveau(MonNode.Parent, False) 
        Return Pos 
    End If 
End Function
Que j'appellerais par exemple avec :

Code vb.net : Sélectionner tout
MsgBox(Niveau(Me.TreeView1.SelectedNode, True).ToString)
Toutefois cette approche n'est souvent pas la meilleure car les procédures récursives sont coûteuses en ressources. Généralement, on connaît à priori le niveau hiérarchique lors de la construction. Il est alors rentable de le stocker dans la propriété Tag de l'objet TreeNode lors de la construction du TreeView.

Mis à jour le 30 octobre 2013 bidou

Nous allons donc créer un remplissage d'un TreeView par la structure d'une base de données Access. Je vais le coder un peu lourd pour séparer l'extraction de la structure du remplissage du TreeView sans utiliser une collection fortement typée.

Code vb.net : Sélectionner tout
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
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    ' Code d'extraction de la structure 
    Dim lstStructure As New SortedList 
    Dim MaConn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\User\NWIND.MDB;") 
    MaConn.Open() 
    Dim schemaTables As DataTable = MaConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"}) 
    Dim MonEnumColonne, MonEnumTable As IEnumerator 
    Dim schemaColTable As DataTable 
    Dim ListColonne As ArrayList 
  
    MonEnumTable = schemaTables.Rows.GetEnumerator 
    While MonEnumTable.MoveNext 
        schemaColTable = MaConn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, New Object() {Nothing, Nothing, CType(MonEnumTable.Current, DataRow).Item("Table_Name"), Nothing}) 
        ListColonne = New ArrayList 
        MonEnumColonne = schemaColTable.Rows.GetEnumerator 
        While MonEnumColonne.MoveNext 
            ListColonne.Add(CType(MonEnumColonne.Current, DataRow).Item("column_name")) 
        End While 
        lstStructure.Add(CType(MonEnumTable.Current, DataRow).Item("Table_Name"), ListColonne) 
    End While 
    MaConn.Close() 
  
    ' Remplissage du treeview 
    Dim NodRoot, NodTable, NodTemp As TreeNode 
    NodRoot = Me.TreeView1.Nodes.Add("biblio.mdb") 
    NodRoot.ImageIndex = 0 
    Dim cmpt1, cmpt2 As Int32 
    Dim MonEnum As IEnumerator 
    For cmpt1 = 0 To lstStructure.Count - 1 
        NodTable = NodRoot.Nodes.Add(CType(lstStructure.GetKey(cmpt1), String)) 
        MonEnum = CType(lstStructure.GetByIndex(cmpt1), ArrayList).GetEnumerator 
        While MonEnum.MoveNext 
            NodTemp = New TreeNode 
            With NodTemp 
                .Text = CType(MonEnum.Current, String) 
                .ImageIndex = 2 
            End With 
            NodTable.Nodes.Add(NodTemp) 
            NodTable.ImageIndex = 1 
        End While 
    Next 
    Me.TreeView1.ImageList = Me.ImageList1 
  
End Sub

Mis à jour le 30 octobre 2013 bidou

Il faut pour cela traiter l'évènement MouseMove du TreeView :

Code vb.net : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
''' <summary> 
'''     Évènement MouseMove du treeView1 
''' </summary> 
  
Private Sub treeView1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)  
  
    'Récupération du TreeNode survolé 
    Dim currentNode As TreeNode = treeView1.GetNodeAt(e.X, e.Y)  
  
    ' Vérification que la souris survole bien un TreeNode 
    If Not (currentNode Is Nothing) Then  
        Console.WriteLine("Le node survolé est {0}", currentNode.Name)  
    End If  
End Sub

Mis à jour le 30 octobre 2013 Jérôme Lambert

Ce bout de code permet de lister les fichiers et sous répertoires d'un répertoire spécifique. À la différence de ma source qui liste un répertoire dans une Listbox, cette méthode avec la TreeView permet de garder la hiérarchie de votre répertoire. Pour y parvenir, c'est un peu plus compliqué que pour la ListBox mais ce n'est pas si dur que ça.

Il faut créer une classe et coller le code ci dessous.

Code vb.net : Sélectionner tout
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
55
56
57
58
59
60
61
62
63
64
65
Imports System.IO 
  
Public Class ListerRepertoire 
    Private TheTreeview As TreeView 
    Private Delegate Function TN_Delegate(ByVal a As TreeNode) As Int32 
  
    Public Sub New(ByVal TV As TreeView) 
        TheTreeview = TV 'affecte la Treeview 
    End Sub 
  
    Public Sub ListerMesRepertoire(ByVal Rep As String, ByVal Parent As TreeNode) 
        Try 
            'Récupère la liste des entrées du répertoire 
            Dim Liste As String() = Directory.GetFileSystemEntries(Rep) 
            Dim Entree As String 
  
            For Each Entree In Liste 'Pour chaque entrée de la liste 
                Dim TmpName As String = Microsoft.VisualBasic.Mid(Entree, Len(Rep) + 1) ' On découpe proprement le nom du fichier ou répertoire 
                TmpName = Microsoft.VisualBasic.Replace(TmpName, "\", "") ' On enlève les caractères parasites ! 
  
                If File.Exists(Entree) Then     ' Si c'est un fichier 
                    AddNode(TmpName, True, Parent)  ' On crée un élément fichier dans le TreeView 
                Else    ' Si  c'est un répertoire 
                    Dim TmpNode As TreeNode 'Var tempo pour sauver le nœud du TreeView 
                    TmpNode = AddNode(TmpName, False, Parent) ' On ajoute le répertoire dans le TreeView 
                    ListerMesRepertoire(Entree, TmpNode) ' On liste le contenus de ce répertoire 
                End If 
            Next Entree 
        Catch Ex As System.UnauthorizedAccessException ' Si le répertoire est protégé 
            Exit Sub 
        Catch e As Exception 'en cas d'erreurs 
            MsgBox("Erreur : " & e.Message, MsgBoxStyle.Critical) 
        End Try 
    End Sub 
  
    Private Function AddNode(ByVal StrNom As String, ByVal BlFile As Boolean, ByVal Parent As TreeNode) As TreeNode 
        Try 
            Dim TmpNode As TreeNode      ' Nœud Pour les manipulations dans la fonction 
  
            If Not Parent Is Nothing Then '  Si Parent n'est pas à Nothing 
                'TmpNode = Parent.Nodes.Add(Str_Nom) ' On crée un élément fils 
                Dim no As New TreeNode 
                no.Text = StrNom 
                With TheTreeview 
                    .Invoke(New TN_Delegate(AddressOf Parent.Nodes.Add), New Object() {no}) 
                End With 
                TmpNode = no 
                Else ' Si Parent Est à Nothing c sans doute le premier élément du TreeView ou une racine 
                     'TmpNode = TreeView1.Nodes.Add(Str_Nom) 
                    Dim no As New TreeNode 
                    no.Text = StrNom 
                With TheTreeview 
                    .Invoke(New TN_Delegate(AddressOf TheTreeview.Nodes.Add), New Object() {no}) 
                End With 
                TmpNode = no 
            End If 
  
            Application.DoEvents()  ' Histoire de faire beau ^^ Non je pense que ça limitera le risque d'erreur 
            Return TmpNode 
        Catch ex As Exception 
            Return Nothing 
            MsgBox(ex.ToString) 
        End Try 
    End Function 
End Class
Ensuite, il faut instancier votre classe et lui fournir le nom de votre TreeView comme argument :

Code vb.net : Sélectionner tout
1
2
3
4
5
6
Private c As ListerRepertoire 
  
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    c = New ListerRepertoire(TreeView1) 'instancie la classe 
    c.ListerMesRepertoire("C:\", Nothing) 'liste le répertoire 
End Sub
Il ne vous reste plus qu'à apprécier la rapidité du code avec un petit BackgroundWorker pour voir la progression (sinon cela de freezer).

Mis à jour le 6 décembre 2013 Aspic

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsable bénévole de la rubrique Microsoft DotNET : Hinault Romaric -