Treeview nodes. clé

Signaler
Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020
-
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
-
Bonjour,

Mon objectif est de créer un nœud enfant avec une clé spécifique en sélectionnant le nœud parent dans mon treeview
TreeViewToolBox
en utilisation ce code ci -dessous:

 Dim StatusDate As String
                StatusDate = InputBox("Saisir le Nom du dossier que vous voulez créer dans " & fils.Text)
                If StatusDate = "" Then
                    MsgBox("Vous devez saisir un Nom.")
                    Exit Sub
                Else        
                Dim trace As String = System.DateTime.Now.ToString("ddMMyyyy" & "HHmmss")
                ' Add(Of String, String)
                Dim newNode As New TreeNode With {.nom = trace, .Text = StatusDate}         
                TreeViewToolBox.SelectedNode.Nodes.Add(newNode)
                Me.Textkey.Text = newNode.nom

  End If
            End If



Dans mon code j'attribue une clé spécifique (trace) à chaque nœud enfant créé.
Ce procédé fonctionne sur le coup car quand je sélectionne le nœud enfant que je viens de créer j'obtiens bien le text
trace
avec ce code
MsgBox(TreeViewToolBox.SelectedNode.nom)
.

Jusqu'ici pas de souci .
Mon treeview est stocké dans une base qui se charge à l'ouverture du Form.

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 Dim conn = New SQLiteConnection("Data Source=BDD.s3db;Version=3")
        Try
            Using (conn)
                conn.Open()
                Dim sql = "Select * FROM ARBORESCENCE"
                Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
                Dim da As New SQLiteDataAdapter
                da.SelectCommand = cmdDataGrid
                Dim dta As New DataTable
                da.Fill(dta)
                dgvDataArbo.DataSource = dta
                TreeViewToolBox.Nodes.Clear()
                For Each dr As DataRow In dta.Rows
                    AddNode(dr("PARENT").ToString, dr("FILS").ToString)
                Next
end if 


Problème :Problème

Après l’ouverture de la Form , j'ai toujours le nœud enfant créé mais sa clé (trace) a disparu !!!

Est ce un souci de stockage dans la BDD , si oui pourriez vous m'aider à créer la clé et conserver la spécifique pour chaque nœud créé?

Merci d'avance

26 réponses

Messages postés
2272
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
23 novembre 2020
115
Bonjour
Tu dis : Après l’ouverture de la Form , j'ai toujours le nœud enfant créé mais sa clé (trace) a disparu !!!
Cette clé est-elle sauvegardé dans la base de données avec le nœud correspondant ?
Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Bonjour VB95
Merci pour ta réponse
C'est bien ça mon problème . je ne sais pas comment ou plutôt ou sauvegarder cette clé dans la BDD.
J'avais pensé créer une colonne nommée Key sur ma BDD mais comment la charger avec le nœud correspondant?
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Bonjour Julia

tu ne montres pas le code qui enregistre dans la base de données.
On ne peut pas te dire ce qu'il faut y modifier.....
Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Bonjour
je te jojns ci dessous le code
  Dim ARBORESCENCE As New m_ARBORESCENCE(0)
If SelID = 0 Then Ajouter2()
Dim conn = New SQLiteConnection("Data Source=BDD.s3db;Version=3")
Using (conn)
conn.Open()
Dim sql = "SELECT * FROM ARBORESCENCE"
Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
Dim da As New SQLiteDataAdapter
da.SelectCommand = cmdDataGrid
Dim dt As New DataTable
da.Fill(dt)
dgvDataArbo.DataSource = dt

End Using
TreeViewToolBox.ExpandAll()
MsgBox("enregistré")



Private Sub Ajouter2()
Dim ARBORESCENCE = New m_ARBORESCENCE(DBNewIndexARBORESCENCE)
ARBORESCENCE.FILS = fils.Text
ARBORESCENCE.INDEXFILS = filsindex.Text
ARBORESCENCE.PARENT = parent.Text
ARBORESCENCE.INDEXPARENT = parentindex.Text
ARBORESCENCE.key = Textkey.Text
DBaddARBORESCENCE(ARBORESCENCE)
End Sub


 Public Sub DBaddARBORESCENCE(ByVal ARBORESCENCE As m_ARBORESCENCE)
Try
Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@Id,@FILS,@INDEXFILS,@PARENT,@INDEXPARENT,@key)"
Dim cmd = New SQLiteCommand(strSQL, CON)
cmd.Parameters.AddWithValue("@ID", ARBORESCENCE.ID)
cmd.Parameters.AddWithValue("@FILS", ARBORESCENCE.FILS)
cmd.Parameters.AddWithValue("@INDEXFILS", ARBORESCENCE.INDEXFILS)
cmd.Parameters.AddWithValue("@PARENT", ARBORESCENCE.PARENT)
cmd.Parameters.AddWithValue("@INDEXPARENT", ARBORESCENCE.INDEXPARENT)
cmd.Parameters.AddWithValue("@key", ARBORESCENCE.key)
cmd.ExecuteNonQuery()
cmd.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try

End Sub
Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Bonjour
Désolée du "code chiffon"
ci dessous avec la coloration Syntaxique

Dim ARBORESCENCE As New m_ARBORESCENCE(0)
                If SelID = 0 Then Ajouter2()
        Dim conn = New SQLiteConnection("Data Source=BDD.s3db;Version=3")
        Using (conn)
            conn.Open()
            Dim sql = "SELECT * FROM ARBORESCENCE"
            Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
            Dim da As New SQLiteDataAdapter
            da.SelectCommand = cmdDataGrid
            Dim dt As New DataTable
            da.Fill(dt)
            dgvDataArbo.DataSource = dt

        End Using
        TreeViewToolBox.ExpandAll()
        MsgBox("enregistré")




Private Sub Ajouter2()
        Dim ARBORESCENCE = New m_ARBORESCENCE(DBNewIndexARBORESCENCE)
        ARBORESCENCE.FILS = fils.Text
        ARBORESCENCE.INDEXFILS = filsindex.Text
        ARBORESCENCE.PARENT = parent.Text
        ARBORESCENCE.INDEXPARENT = parentindex.Text
        ARBORESCENCE.key = Textkey.Text
        DBaddARBORESCENCE(ARBORESCENCE)
    End Sub


Public Sub DBaddARBORESCENCE(ByVal ARBORESCENCE As m_ARBORESCENCE)
        Try
            Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@Id,@FILS,@INDEXFILS,@PARENT,@INDEXPARENT,@key)"
            Dim cmd = New SQLiteCommand(strSQL, CON)
            cmd.Parameters.AddWithValue("@ID", ARBORESCENCE.ID)
            cmd.Parameters.AddWithValue("@FILS", ARBORESCENCE.FILS)
            cmd.Parameters.AddWithValue("@INDEXFILS", ARBORESCENCE.INDEXFILS)
            cmd.Parameters.AddWithValue("@PARENT", ARBORESCENCE.PARENT)
            cmd.Parameters.AddWithValue("@INDEXPARENT", ARBORESCENCE.INDEXPARENT)
            cmd.Parameters.AddWithValue("@key", ARBORESCENCE.key)
            cmd.ExecuteNonQuery()
            cmd.Dispose()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub
Messages postés
2272
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
23 novembre 2020
115
Bonjour
Dans ton premier message tu as bien utilisé la coloration syntaxique . Pourquoi ne pas l'avoir utilisé dans ton dernier message ?
De plus dans tout code un minimum de commentaires est plus que bénéfique . Cela permet de savoir ce que le code fait et de plus dans quelques temps si tu reviens sur ce code ces indications te seront précieuses .
Tertio dans le premier bloc de code la procédure n'est pas complète . Du coup difficile pour nous de comprendre exactement le rôle de chaque procédure .

Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Ici, il te faut un champ supplémentaire dans la base de données et y enregistrer la valeur de trace

 Public Sub DBaddARBORESCENCE(ByVal ARBORESCENCE As m_ARBORESCENCE)
        Try
            Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@Id,@FILS,@INDEXFILS,@PARENT,@INDEXPARENT,@key)"
            Dim cmd = New SQLiteCommand(strSQL, CON)
            cmd.Parameters.AddWithValue("@ID", ARBORESCENCE.ID)
            cmd.Parameters.AddWithValue("@FILS", ARBORESCENCE.FILS)
            cmd.Parameters.AddWithValue("@INDEXFILS", ARBORESCENCE.INDEXFILS)
            cmd.Parameters.AddWithValue("@PARENT", ARBORESCENCE.PARENT)
            cmd.Parameters.AddWithValue("@INDEXPARENT", ARBORESCENCE.INDEXPARENT)
            cmd.Parameters.AddWithValue("@key", ARBORESCENCE.key)
            cmd.ExecuteNonQuery()
            cmd.Dispose()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub



Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Effectivement ,
cmd.Parameters.AddWithValue("@key", ARBORESCENCE.key)

permet d'enregistrer la valeur de trace .
Mais comment la recharger en tant que clé ?
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Bonjour

dans la procédure
 sub DBaddARBORESCENCE (ByVal ARBORESCENCE As m_ARBORESCENCE)
tu enregistres des objets de types m_ARBORESCENCE qui à priori viennent de tes noeuds de treeview.

Mais le code de lecture de base de données charge un datagridview (pas de trevieew) sans créer d'instances de m_ARBORESCENCE.
Donc soit tu n'as pas montré le bon code, soit c'est pas cohérent.

Si tu veux enregistre des serviettes, il faut lire des serviettes, pas des torchons.

Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Bonjour merci de ta réponse
dans la procédure sub DBaddARBORESCENCE (ByVal ARBORESCENCE As m_ARBORESCENCE)

tu enregistres des objets de types m_ARBORESCENCE qui à priori viennent de tes nœuds de treeview.
.


Oui c'est bien ça

Mais le code de lecture de base de données charge un datagridview (pas de trevieew) sans créer d'instances de m_ARBORESCENCE.

le datagridview et le treeview ont la même source

'''A l'ouverture de la form 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'''Connxion à la base de donnée BDD et acces à la table ARBORESCENCE
 Dim conn = New SQLiteConnection("Data Source=BDD.s3db;Version=3")
        Try
            Using (conn)
                conn.Open()
                Dim sql = "Select * FROM ARBORESCENCE"
                Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
                Dim da As New SQLiteDataAdapter
                da.SelectCommand = cmdDataGrid
'datatable dta crée qui va enrichir la BDD et treeview
                Dim dta As New DataTable
                da.Fill(dta)
''BDD ARBORESEBCE alimentéé
                dgvDataArbo.DataSource = dta
''épuration du treeview
                TreeViewToolBox.Nodes.Clear()

''Alimentation du treeview
                For Each dr As DataRow In dta.Rows
                    AddNode(dr("PARENT").ToString, dr("FILS").ToString)
                Next
end if 



Merci de votre soutien
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Mais dans un sens il y a des m_ARBORESCENCE et dans l'autre des lignes.

Ça ne "couche" pas ensemble, il faut des m_ARBORESCENCE dans les 2 sens, ou peu importe le type mais le même.
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Je ne peux pas essayer ton code car, il en manque des morceaux utiles (AddNode par exemple) et surtout je n'ai pas trouvé d'où sortent les classes SQLiteConnection, SQLiteCommand et SQLiteDataAdapter

J'ai donc essayé de te faire un exemple avec un csv.
J'ai imaginé que ta classe métier dérive de TreeNode.
Imports System.Windows.Forms

Class NoeudJulia
    Inherits TreeNode

    Public Property ID As Integer
    Public Property IdParent As Integer
    Public Property IdEnfant As Integer
    Public Property Enfant As NoeudJulia
End Class

Y'a qu'un enfant par noeud pour simplifier l'exemple

J'ai un formulaire avec 3 boutons, un datagridview et un treeview.
Le 1er bouton crée une liste de 4 noeuds, qu'on pourra ensuite enregistrer en CSV avec le bouton adéquat.
Le dernier bouton lit charge fichier csv dans la liste.

Que la liste soit créée par le bouton ou lue dans le csv, elle est affichée dans le datagridview et le treeview

Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.IO
Imports System.Linq
Imports System.Windows.Forms

Public Partial Class frmJulia
    Inherits Form

    Private fichierCsv As String = "noeudsJulia.csv"

    Public Sub New()
        InitializeComponent()

        'si le fichier existe déjà, il faut le lire 
        If File.Exists(fichierCsv) Then butCreerListe.Enabled = False

        butLire.Enabled = Not butCreerListe.Enabled
    End Sub

    Private noeuds As List(Of NoeudJulia)

        ''' <summary>
        '''Création de la liste "neuve"
        '''</summary>
        ''' <param name="sender"></param>
        '''<param name="e"></param>
    Private Sub butCreerListe_Click(ByVal sender As Object, ByVal e As EventArgs)
        noeuds = New List(Of NoeudJulia) From {
            New NoeudJulia With {
                .ID = 1,
                .IdEnfant = 2,
                .IdParent = 0,
                .Name = "Nom 1",
                .Text = "Nom 1"
            },
            New NoeudJulia With {
                .ID = 2,
                .IdEnfant = 3,
                .IdParent = 1,
                .Name = "Nom 2",
                .Text = "Nom 2"
            },
            New NoeudJulia With {
                .ID = 3,
                .IdEnfant = 4,
                .IdParent = 2,
                .Name = "Nom 3",
                .Text = "Nom 3"
            },
            New NoeudJulia With {
                .ID = 4,
                .IdEnfant = 0,
                .IdParent = 3,
                .Name = "Nom 4",
                .Text = "Nom 4"
            }
        }
        AfficheNoeuds()
    End Sub

        ''' <summary>
        ''' Affiche la liste en cours
        ''' </summary>
    Private Sub AfficheNoeuds()
        dataGridView1.DataSource = Nothing
        dataGridView1.DataSource = noeuds
        treeView1.Nodes.Clear()

        For Each n As NoeudJulia In noeuds
            n.Enfant = noeuds.SingleOrDefault(Function(x) x.ID = n.IdEnfant)

            If n.IdParent = 0 Then
                treeView1.Nodes.Add(n)
            Else
                treeView1.SelectedNode.Nodes.Add(n)
            End If

            treeView1.SelectedNode = n
        Next
    End Sub

        ''' <summary>
        ''' Enregistrement dans le fichier CSV
        ''' </summary>
        '''<param name="sender"></param>
        ''' <param name="e"></param>
    Private Sub butEnregistrer_Click(ByVal sender As Object, ByVal e As EventArgs)
        File.WriteAllLines(fichierCsv, noeuds.[Select](Function(n) String.Format("{0};{1};{2};{3}", n.ID, n.IdParent, n.IdEnfant, n.Name)))
        butCreerListe.Enabled = False
        butLire.Enabled = True
    End Sub

    Private Sub butLire_Click(ByVal sender As Object, ByVal e As EventArgs)
        noeuds = (From ligne In File.ReadAllLines(fichierCsv) Let tab = ligne.Split(";"c) Select New NoeudJulia With {
            .ID = Convert.ToInt32(tab(0)),
            .IdParent = Convert.ToInt32(tab(1)),
            .IdEnfant = Convert.ToInt32(tab(2)),
            .Name = tab(3),
            .Text = tab(3)
        }).ToList()
        AfficheNoeuds()
    End Sub
End Class




Peux tu tester ça dans un projet à part et me dire si cela ressemble à ce que tu cherches à faire?
Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Bonjour Wishmeril
Gros merci pour ce super job .
Tu as bien compris à 80% mes soucis meme si moi j'utilise
 Dim trace As String = System.DateTime.Now.ToString("ddMMyyyy" & "HHmmss")
 ' Add(Of String, String)
   Dim newNode As New TreeNode With {.Name = trace, .Text = StatusDate}
  'Dim newNode As TreeNode = New TreeNode(StatusDate)
  TreeViewToolBox.SelectedNode.Nodes.Add(newNode)

Dans ton exemple , les nœuds parent et fils avec le name (clé unique) sont crées et le datagridiview est renseigné .ok
je peux stocker tout ça dans une BDD qui servira de source à l'ouverture. ok
Mais comment charger la clé unique (name) attribuée a chaque noeud ?
mon code c'est
''Alimentation du treeview
                For Each dr As DataRow In dta.Rows
                    AddNode(dr("PARENT").ToString, dr("FILS").ToString)
                Next
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Mon exemple avait pour but de te montrer que si j'enregistre des instances de Machin, pour récupérer toutes les données, à la lecture il faut créer des instances de Machin.

Tu montres, encore et toujours un code qui crée des Nodes et des lignes de datagridview alors que tu as enregistré des instances de m_ARBORESCENCE

La propriété Name ne doit pas être un identifiant unique.
C'est bien pour cela que l'objet que j'ai écrit comme exemple (NoeudJulia) dispose d'une propriété dédiée ID et 2 propriétés IdParent, et IdEnfant (en pratique on devrait pouvoir se débrouiller, juste avec IdParent).

Pour pouvoir t'aider au mieux, il nous faut avant tout cerner ton besoin, il nous manque
  • le code de AddNode (ça je l'ai déjà écrit)
  • le code de m_ARBORESCENCE
  • d'où viennent tes classes de connexion (ça aussi je l'ai déjà écrit)
  • peut il y avoir plusieurs enfants par parent ?


Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Bonsoir
le code de AddNode (ça je l'ai déjà écrit)
 Public Sub AddNode(parentNode As String, nodeText As String)
        Dim node As New List(Of TreeNode)
        node.AddRange(TreeViewToolBox.Nodes.Find(parentNode, True))
        If Not node.Any Then
            node.Add(TreeViewToolBox.Nodes.Add(parentNode, parentNode))
        End If
        node(0).Nodes.Add(nodeText, nodeText)
    End Sub


le code de m_ARBORESCENCE

Private Sub Ajouter2()
        Dim ARBORESCENCE = New m_ARBORESCENCE(DBNewIndexARBORESCENCE)
        ARBORESCENCE.FILS = fils.Text
        ARBORESCENCE.INDEXFILS = filsindex.Text
        ARBORESCENCE.PARENT = parent.Text
        ARBORESCENCE.INDEXPARENT = parentindex.Text
        DBaddARBORESCENCE(ARBORESCENCE)
    End Sub


d'où viennent tes classes de connexion (ça aussi je l'ai déjà écrit)

  Public Structure m_ARBORESCENCE

        Dim ID As Integer
        Dim FILS As String
        Dim INDEXFILS As String
        Dim PARENT As String
        Dim INDEXPARENT As String

        Public Sub New(ByVal Idx1 As Integer)
            ID = Idx1
            FILS = ""
            INDEXFILS = 0

        End Sub
    End Structure


peut il y avoir plusieurs enfants par parent ?
oui bien sur


vraiment merci de te pencher sur mes lacunes
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Bonjour Julia,

le code de m_Arborescence c'est celui-ci
Public Structure m_ARBORESCENCE

        Dim ID As Integer
        Dim FILS As String
        Dim INDEXFILS As String
        Dim PARENT As String
        Dim INDEXPARENT As String

        Public Sub New(ByVal Idx1 As Integer)
            ID = Idx1
            FILS = ""
            INDEXFILS = 0

        End Sub
    End Structure


C'est une structure, admettons, c'est pas trop .Net et gourmand en mémoire, mais ça marche.
Par contre tu dis
peut il y avoir plusieurs enfants par parent ?
oui bien sur
et le membre Fils est juste une string. Il serait plus logique que ce soit une collection de m_Arborescence (une liste par exemple).

Quand je te demande d'où viennent tes classes connexions, je parle de SQLiteCommand et SQLiteDataAdapter. Celles que j'ai trouvées sur le net ne correspondent pas à ton code.

Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Bonjour Whismeril

je te passe l'ensemble des codes du module modSQLite.vb

Imports System.Data.SQLite
Imports System.IO
Module modSQLITE
    Public Database As String
    Dim CON As New SQLiteConnection
 
    Public Sub OpenDataBase()
        Try
            Database = My.Application.Info.DirectoryPath & "\BDD.s3db"
            CON.ConnectionString = "Data Source=" & Database
            CON.Open()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    '
    Public Sub CloseDatabase()
        CON.Close()
    End Sub
 

    Public Structure m_ARBORESCENCE

        Dim ID As Integer
        Dim FILS As String
        Dim INDEXFILS As String
        Dim PARENT As String
        Dim INDEXPARENT As String
        Dim key As String

        Public Sub New(ByVal Idx1 As Integer)
            ID = Idx1
            FILS = ""
            INDEXFILS = 0
            key = 0

        End Sub
    End Structure

    Public Sub DBaddARBORESCENCE(ByVal ARBORESCENCE As m_ARBORESCENCE)
        Try
            Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@Id,@FILS,@INDEXFILS,@PARENT,@INDEXPARENT,@key)"
            Dim cmd = New SQLiteCommand(strSQL, CON)
            cmd.Parameters.AddWithValue("@ID", ARBORESCENCE.ID)
            cmd.Parameters.AddWithValue("@FILS", ARBORESCENCE.FILS)
            cmd.Parameters.AddWithValue("@INDEXFILS", ARBORESCENCE.INDEXFILS)
            cmd.Parameters.AddWithValue("@PARENT", ARBORESCENCE.PARENT)
            cmd.Parameters.AddWithValue("@INDEXPARENT", ARBORESCENCE.INDEXPARENT)
            cmd.Parameters.AddWithValue("@key", ARBORESCENCE.key)
            cmd.ExecuteNonQuery()
            cmd.Dispose()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub

    Public Function DBgetARBORESCENCE(ByVal Idx As Integer) As m_ARBORESCENCE
        Dim strSQL As String = "SELECT * FROM ARBORESCENCE WHERE ID= " & Idx
        Dim ARBORESCENCE As New m_ARBORESCENCE
        Dim cmd = New SQLiteCommand(strSQL, CON)
        Dim DR As SQLiteDataReader = cmd.ExecuteReader
       
        While (DR.Read())
            ARBORESCENCE.ID = DR(0)
            ARBORESCENCE.FILS = DR(1)
            ARBORESCENCE.INDEXFILS = DR(2)
            ARBORESCENCE.PARENT = DR(3)
            ARBORESCENCE.INDEXPARENT = DR(4)
        End While
        DR.Close()
        cmd.Dispose()
        Return ARBORESCENCE
    End Function

    Public Sub DBdeleteARBORESCENCE(ByVal Idx1 As Integer)
        Dim strSQL As String = "DELETE FROM ARBORESCENCE WHERE ID= " & Idx1
        Dim cmd = New SQLiteCommand(strSQL, CON)
        cmd.ExecuteNonQuery()
        cmd.Dispose()
    End Sub

    Public Function DBNewIndexARBORESCENCE() As Integer
        Dim NewID As Integer = 1
        Dim cmd = New SQLiteCommand("SELECT MAX(ID) FROM ARBORESCENCE", CON)
        Try
            Dim DR As SQLiteDataReader = cmd.ExecuteReader
            While (DR.Read())
                NewID = DR(0)
            End While
            DR.Close()
            Return NewID + 1
        Catch ex As Exception
            Return NewID
        End Try
    End Function
End Module
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Bonjour Whismeril

Je te joins dans le lien ci dessous mon projet "brut" pour plus de visibilité .

https://www.cjoint.com/c/JKwjUPiPFEZ

En gros mon souci depuis 3 jours ( Grrr!!!) c'est d'affecter une clé fixe au noeud créé: Clé qui sera la valeur de trace dans mon projet .
Cette clé , une fois crée va être stocké dans la BDD dans la colonne "Key" . Et elle doit être chargée toujours comme clé du noeud correspondant quand je Load le treeview. Ce qui n’est pas le cas .

L'utilité de cette clé sera de pouvoir toujours repérer son noeud dans la BDD et de pouvoir agir dessus .

Merci de ton aide .
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Je n'ai pas ouvert ton projet, j'ai écrit le mien.

D'abord avec un éditeur de bdd sqlite, j'ai créé une base de test, mon éditeur ne gère pas l'extension que tu as utilisée, alors je l'ai appelée BDD.db
Voici sa structure,


Il est impératif que ID soit unique et auto incrément

Voici les données de départ


Voici 2 classes (je t'expliquerai plus tard si ce code te convient pourquoi il ne faut pas que ce soit des structures)
La premiere c'est ma version de m_arborescence, la seconde dérive de TreeNode et contient un m_arborescence (comme ça c'est toujours lié)

Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SQLite
Imports System.Linq
Imports System.Windows.Forms

''' <summary>
''' Classe métier
''' </summary>
Public Class m_ARBORESCENCE
    ''' <summary>
    ''' Construction d'une instance à partir d'une ligne de bdd
    ''' </summary>
    Public Sub New(ByVal DR As DataRow)
        Nom = DR("Nom").ToString()
        ID = Convert.ToInt32(DR("ID"))
        IdParent = Convert.ToInt32(DR("IdParent"))
    End Sub

    ''' <summary>
    ''' Construction d'une instance à partir des données saisies
    ''' </summary>
    Public Sub New(ByVal LeNom As String, ByVal LIdParent As Integer, ByVal CON As SQLiteConnection)
        Nom = LeNom
        IdParent = LIdParent
        InsertBdd(CON)
    End Sub

    ''' <summary>
    ''' Insère cette nouvelle valeur dans la BDD et récupère l'ID
    ''' </summary>
    ''' <param name="CON"></param>
    Private Sub InsertBdd(ByVal CON As SQLiteConnection)
        Try
            Dim strSQL As String = "INSERT INTO ARBORESCENCE VALUES (@ID,@Nom,@IdParent)"
            Dim cmd = New SQLiteCommand(strSQL, CON)
            cmd.Parameters.AddWithValue("@IdParent", IdParent)
            cmd.Parameters.AddWithValue("@Nom", Nom)
            cmd.Parameters.AddWithValue("@ID", Nothing) 'pour que l'auto incrément s'active
            cmd.ExecuteNonQuery()
            cmd.Dispose()
            Dim sql As String = "Select last_insert_rowid() FROM ARBORESCENCE"
            cmd = New SQLiteCommand(sql, CON)
            ID = Convert.ToInt32(cmd.ExecuteScalar()) 'on récupère l'id créé
            cmd.Dispose()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Public Property Nom As String
    Public Property ID As Integer
    Public Property IdParent As Integer
End Class

''' <summary>
''' Classe qui associe une donnée de la BDD et son apparence en TreeNode
''' </summary>
Public Class NoeudJulia
    Inherits TreeNode

    ''' <summary>
    ''' Construction d'une instance de NoeudJulia, à partir d'une ligne de la BDD
    ''' </summary>
    ''' <param name="DR"></param>
    ''' <param name="LesNoeuds"></param>
    Public Sub New(ByVal DR As DataRow, ByVal LesNoeuds As List(Of NoeudJulia))
        MyBase.New()
        Valeur = New m_ARBORESCENCE(DR)
        Text = Valeur.Nom

        If Valeur.IdParent = 0 Then
            LesNoeuds.Clear()
        Else
            Dim pere As NoeudJulia = LesNoeuds.SingleOrDefault(Function(nj) nj.Valeur.ID = Valeur.IdParent)
            If pere Is Nothing Then Throw New Exception("Parent introuvable")
            pere.Nodes.Add(Me)
        End If

        LesNoeuds.Add(Me)
    End Sub

    ''' <summary>
    ''' Création d'un NoeudJulia à partir des données saisies
    ''' </summary>
    ''' <param name="Nom"></param>
    ''' <param name="Parent"></param>
    ''' <param name="LesNoeuds"></param>
    Public Sub New(ByVal Nom As String, ByVal Parent As NoeudJulia, ByVal LesNoeuds As List(Of NoeudJulia), ByVal CON As SQLiteConnection)
        MyBase.New(Nom)
        Valeur = New m_ARBORESCENCE(Nom, Parent.Valeur.ID, CON)
        Parent.Nodes.Add(Me)
        LesNoeuds.Add(Me)
    End Sub

    Public Property Valeur As m_ARBORESCENCE
End Class


Et voilà un formulaire avec un treeview, un datagridview et un bouton
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Imports System.Windows.Forms
Imports System.Data.SQLite

Public Partial Class frmJulia
    Inherits Form

    Private Database As String
    Private CON As SQLiteConnection = New SQLiteConnection()

    Private Sub OpenDataBase()
        Try
            Database = String.Format("{0}\BDD.db", Application.StartupPath)
            CON.ConnectionString = "Data Source=" & Database
            CON.Open()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Public Sub New()
        InitializeComponent()
    End Sub

    'liste qui va accueuillir les noeuds
    Private lesNoeuds As List(Of NoeudJulia) = New List(Of NoeudJulia)()

    Private Sub ChargeBdd()
        Dim conn As SQLiteConnection = New SQLiteConnection("Data Source=BDD.db;Version=3")

        Try

            Using (conn)
                conn.Open()
                Dim sql As String = "Select * FROM ARBORESCENCE ORDER BY IdParent" 'il est impératif pour la suite que le datareader soit trié de la sorte
                Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
                Dim da As SQLiteDataAdapter = New SQLiteDataAdapter()
                da.SelectCommand = cmdDataGrid
                Dim dta As DataTable = New DataTable()
                da.Fill(dta)

                'lecture des données et création de la liste de NoeudJulia
                For Each dr As DataRow In dta.Rows
                    New NoeudJulia(dr, lesNoeuds)
                Next
            End Using

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    ''' <summary>
    ''' Affiche les données, ordonnées par leur ID
    ''' </summary>
    Private Sub AfficheDatas()
        treeView1.Nodes.Clear()
        treeView1.Nodes.Add(lesNoeuds(0))
        Dim lesValeur = lesNoeuds.[Select](Function(nj) nj.Valeur).OrderBy(Function(v) v.ID)
        dataGridView1.DataSource = Nothing
        dataGridView1.DataSource = lesValeur.ToList()
    End Sub

    Private Sub frmJulia_Load(ByVal sender As Object, ByVal e As EventArgs)
        OpenDataBase()
        ChargeBdd()
        AfficheDatas()
    End Sub

    ''' <summary>
    ''' Ajoute une valeur au noeud sélectionné, le nom est la date et l'heure
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub butAjouter_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim parent As NoeudJulia = CType(treeView1.SelectedNode, NoeudJulia)
        Dim nouveau As NoeudJulia = New NoeudJulia(DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"), parent, lesNoeuds, CON)
        AfficheDatas()
    End Sub
End Class



Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

J'y suis , je monte tes codes ,
j'aime bein l'idée de l'ID unique
Mais J'ai une erreur de syntaxe sur new
'lecture des données et création de la liste de NoeudJulia
                For Each dr As DataRow In dta.Rows
                    New NoeudJulia(dr, lesNoeuds)
                Next
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462 >
Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

j'aime bein l'idée de l'ID unique
elle n'est pas de moi cette idée, c'est "juste" l'état de l'art.

Peux tu donner le texte de l'erreur?
Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

Le texte de l'erreur

L'exception System.NullReferenceException n'a pas été gérée
HResult=-2147467261
Message=La référence d'objet n'est pas définie à une instance d'un objet.
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Ok,
en fait, je ne code pas en vb.net, mais en C# et je passe par un convertisseur.
Dans 99.9% des cas ça marche bien et donc avec le temps j'ai perdu l'habitude de tester le code converti.

On est tombé dans le cas où il y a une subtilité que le convertisseur n'a pas géré.

Remplace la boucle par celle-ci
                For Each dr As DataRow In dta.Rows
                    Dim nouveau As New NoeudJulia(dr, lesNoeuds)
                Next

Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

J'obtiens une erreur sur la connexion CON
Public Sub New(ByVal Nom As String, ByVal Parent As NoeudJulia, ByVal LesNoeuds As List(Of NoeudJulia), ByVal CON As SQLiteConnection)
        MyBase.New(Nom)
        Valeur = New m_ARBORESCENCE(Nom, Parent.Valeur.ID, CON)
        Parent.Nodes.Add(Me)
        LesNoeuds.Add(Me)
    End Sub


l'erreur c'est : L'exception System.NullReferenceException n'a pas été gérée
HResult=-2147467261
Message=La référence d'objet n'est pas définie à une instance d'un objet.
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Quand j'ai fait le test en fait, le lien avec les évènements load du formulaire et click du bouton ne se sont pas fait.
Il m'a fallu double cliquer sur le bouton et le formulaire en mode desgin et copier coller les codes dans les 2 nouvelles méthodes crées.
Ça vient peut-être de là.
Messages postés
486
Date d'inscription
jeudi 27 mars 2014
Statut
Membre
Dernière intervention
23 novembre 2020

J'avoue que je n'ai pas trop bien compris
j'ai fait ça
Private Sub frmJulia_Load_1(sender As Object, e As EventArgs) Handles MyBase.Load

        Dim parent As NoeudJulia = CType(TreeView1.SelectedNode, NoeudJulia)
        Dim nouveau As NoeudJulia = New NoeudJulia(DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"), parent, lesNoeuds, CON)
        AfficheDatas()

    End Sub


toujours même erreur
peux tu m'envoyer l'ensemble de la solution de ton exemple ?
Messages postés
2272
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
23 novembre 2020
115
Bonjour Julia et Whismeril

Pour Julia
il faut reprendre pour le code de ta Form principale le code que t'as donné Whismeril au message 20
il te manque juste les
Handles
qui vont raccrocher les Sub aux évènements FormJulia_Load et butAjouter_Click

voici le code complet de la Form avec les 2 Handles manquants

Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Imports System.Windows.Forms
Imports System.Data.SQLite

Public Partial Class frmJulia
    Inherits Form

    Private Database As String
    Private CON As SQLiteConnection = New SQLiteConnection()

    Private Sub OpenDataBase()
        Try
            Database = String.Format("{0}\BDD.db", Application.StartupPath)
            CON.ConnectionString = "Data Source=" & Database
            CON.Open()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Public Sub New()
        InitializeComponent()
    End Sub

    'liste qui va accueuillir les noeuds
    Private lesNoeuds As List(Of NoeudJulia) = New List(Of NoeudJulia)()

    Private Sub ChargeBdd()
        Dim conn As SQLiteConnection = New SQLiteConnection("Data Source=BDD.db;Version=3")

        Try

            Using (conn)
                conn.Open()
                Dim sql As String = "Select * FROM ARBORESCENCE ORDER BY IdParent" 'il est impératif pour la suite que le datareader soit trié de la sorte
                Dim cmdDataGrid As SQLiteCommand = New SQLiteCommand(sql, conn)
                Dim da As SQLiteDataAdapter = New SQLiteDataAdapter()
                da.SelectCommand = cmdDataGrid
                Dim dta As DataTable = New DataTable()
                da.Fill(dta)

                'lecture des données et création de la liste de NoeudJulia
                For Each dr As DataRow In dta.Rows
                    New NoeudJulia(dr, lesNoeuds)
                Next
            End Using

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    ''' <summary>
    ''' Affiche les données, ordonnées par leur ID
    ''' </summary>
    Private Sub AfficheDatas()
        treeView1.Nodes.Clear()
        treeView1.Nodes.Add(lesNoeuds(0))
        Dim lesValeur = lesNoeuds.[Select](Function(nj) nj.Valeur).OrderBy(Function(v) v.ID)
        dataGridView1.DataSource = Nothing
        dataGridView1.DataSource = lesValeur.ToList()
    End Sub

    Private Sub frmJulia_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        OpenDataBase()
        ChargeBdd()
        AfficheDatas()
    End Sub

    ''' <summary>
    ''' Ajoute une valeur au noeud sélectionné, le nom est la date et l'heure
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub butAjouter_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butAjouter.Click
        Dim parent As NoeudJulia = CType(treeView1.SelectedNode, NoeudJulia)
        Dim nouveau As NoeudJulia = New NoeudJulia(DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"), parent, lesNoeuds, CON)
        AfficheDatas()
    End Sub
End Class


Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Salut VB
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Voici un projet fonctionnel.
https://www.cjoint.com/c/JKwqz7xDkr1

Cela dit, tu n'as jamais répondu à la question de savoir quelle bibliothèque tu utilises dans le tien pour te connecter à SQlite.
J'ai supposé qu'il s'agit de celle-ci https://system.data.sqlite.org/index.html/doc/trunk/www/index.wiki si ça n'est pas le cas ça peut expliquer des écarts.
Cette bibliothèque s'installe comme package Nuggets avec ses dépendances (6 packages en tout) c'est trop gros pour cjoint, donc dans le zip il n'y pas pas tout le package mais juste le strict nécessaire (les dll)
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
J'ai pris le temps de jeter un oeil à ton projet, à priori c'est bien la même bibliothèque, à ceci près que la tienne est une veille version (2013)
Messages postés
15135
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 novembre 2020
462
Bonsoir, je viens de m'apercevoir d'une autre erreur du convertisseur.
Il a mis des By Val dans toutes les signatures de méthode.

Pour certaine, ça ne porte pas trop à conséquence (perte de temps d'exécution et utilisation inutile de la mémoire) mais pour d'autres, il y a perte d'informations.

Il faut donc supprimer tous les By Val du projet que je t'ai envoyé.