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 :

DataGridView et fichiers XML


Sujet :

VB.NET

  1. #21
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par realtux Voir le message
    Je sais que c'est considéré comme une mauvaise pratique en objet je suis en plein dedans en cour mais dans la doc de la sérialisation j'ai vu qu'il fallait les mettre en public.
    Il faut mettre en public les membres que tu veux sérialiser. Mais tu ne vas pas sérialiser les champs ET les propriétés, vu qu'ils représentent la même donnée... Donc tu mets les champs en privés, et les propriétés en public

    Citation Envoyé par realtux Voir le message
    sinon en modifiant le code comme tu me la écris, j'ai maintenant cette erreur :

    Une erreur s'est produite lors de la réflexion du type 'System.Collections.Generic.List`1[test.fenetre1.operation]'.


    Je n'ai toujours pas remis les geteur et seteur avant ce test c'est peut être liée ou rien à voir ?
    Ben je sais pas, le message d'erreur est pas assez précis... dans le dialogue d'exception, clic sur Détails et regarde la propriété InnerException. Si le message est encore trop générique, regarde la InnerException au niveau inférieur (c'est à dire la InnerException de la InnerException...).

    Si ta classe operation est sérialisable, une liste d'opérations doit être sérialisable aussi...

  2. #22
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    Pardon mais à quoi correspond les "champs" dans mon code ? car je sais qu'un objet et constitué de propriétés et méthodes mais des champs j'en ai pas entendu parlé jusque la.

  3. #23
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Un champ, c'est un membre d'une classe qui contient des données
    Une propriété, en fait c'est une méthode (ou plus souvent une paire de méthodes : get et set) qui se présente comme un champ, mais qui ne contient pas elle-même de données.

    Par exemple, dans ton cas, ceci est un champ :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            Private dateO As String
    Et ceci est une propriété qui permet d'accéder au champ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            Property dateC() As String
                Get
                    Return dateO
                End Get
                Set(ByVal Value As String)
                    dateO = Value
                End Set
            End Property
    Regarde sur MSDN pour plus d'explications
    http://msdn.microsoft.com/fr-fr/library/a67b72ea.aspx

  4. #24
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    Haaaaa ba enfin mais c'est étrange voila tous :

    J'ai remis les geteur et seteur et changé les propriétés en privées, je constate que les éléments on été générés avec le nom des geteurs ce qui est assez gênant car je ne peut pas structuré mon code xml comme tu me la montrée avec le lien.

    Comme tu l'avais prédis j'obtiens "<ArrayOfOperation>" comme racine

    Voici globalement mon code :

    classe opération (je changerais le nom plus tard) :

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     Public Class operation 'declaration de de la classe opération
            <XmlElement("Budget")> _
            <XmlElement("Date")> Private dateO As String
            <XmlElement("Type")> Private type As String
            <XmlElement("Description")> Private desc As String
            <XmlElement("Debit")> Private debit As String
            <XmlElement("Credit")> Private credit As String
            <XmlElement("Solde")> Private solde As String
     
            '  parametre du constructeur
            Public Sub New(ByVal dateO As String, ByVal type As String, ByVal desc As String, ByVal debit As String, ByVal credit As String, ByVal solde As String)
                Me.dateO = dateO
                Me.type = type
                Me.desc = desc
                Me.debit = debit
                Me.credit = credit
                Me.solde = solde
     
            End Sub
            Public Sub New()
     
            End Sub
     
            Property dateC() As String '   
                Get
                    Return dateO
                End Get
                Set(ByVal Value As String)
                    dateO = Value
                End Set
            End Property
            Property typeC() As String '   
                Get
                    Return type
                End Get
                Set(ByVal Value As String)
                    type = Value
                End Set
            End Property
            Property descC() As String '   
                Get
                    Return desc
                End Get
                Set(ByVal Value As String)
                    desc = Value
                End Set
            End Property
            Property debitC() As String '   
                Get
                    Return debit
                End Get
                Set(ByVal Value As String)
                    debit = Value
                End Set
            End Property
     
            Property creditC() As String '   
                Get
                    Return credit
                End Get
                Set(ByVal Value As String)
                    credit = Value
                End Set
            End Property
     
            Property soldeC() As String '   
                Get
                    Return solde
                End Get
                Set(ByVal Value As String)
                    solde = Value
                End Set
            End Property
    Sérialisation de la liste contentent un objet (histoire de tester)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Dim lst As List(Of operation)
     
            lst = New List(Of operation)
     
            lst.Add(New operation("23/11/2009", "cheque", "Gaz Oil", "100", "0", "900"))
     
            tope.DataSource = lst
     
            Dim xs As XmlSerializer
            xs = New XmlSerializer(GetType(List(Of operation)))
     
            Using sw As New StreamWriter("ope.xml")
                xs.Serialize(sw, lst)
            End Using
    XML généré :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="utf-8"?>
    <ArrayOfOperation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <operation>
        <dateC>23/11/2009</dateC>
        <typeC>cheque</typeC>
        <descC>Gaz Oil</descC>
        <debitC>100</debitC>
        <creditC>0</creditC>
        <soldeC>900</soldeC>
      </operation>
    </ArrayOfOperation>

    OK pour la notion de champs, je confondait certaines appellations car j'ai pas appris les objet de cette façon (mais avec des diagrammes UML +propriété et -méthodes). Ton explication est plus détaillés

  5. #25
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par realtux Voir le message
    J'ai remis les geteur et seteur et changé les propriétés en privées
    Euh, là c'est les champs que tu as mis en privé, pas les propriétés...

    Citation Envoyé par realtux Voir le message
    je constate que les éléments on été générés avec le nom des geteurs ce qui est assez gênant car je ne peut pas structuré mon code xml comme tu me la montrée avec le lien.
    Ben oui, tu n'as pas mis les attributs sur les propriétés, mais sur les champs, qui sont privés et ne sont donc pas sérialisés... D'ailleurs tu as mis 2 attributs XmlElement sur le même champ, ce qui n'a pas de sens.

    Avec le code suivant ça devrait marcher mieux :

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     Public Class operation 'declaration de de la classe opération
            Private dateO As String
            Private type As String
            Private desc As String
            Private debit As String
            Private credit As String
            Private solde As String
     
            '  parametre du constructeur
            Public Sub New(ByVal dateO As String, ByVal type As String, ByVal desc As String, ByVal debit As String, ByVal credit As String, ByVal solde As String)
                Me.dateO = dateO
                Me.type = type
                Me.desc = desc
                Me.debit = debit
                Me.credit = credit
                Me.solde = solde
     
            End Sub
            Public Sub New()
     
            End Sub
     
            <XmlElement("Date")>
            Property dateC() As String '   
                Get
                    Return dateO
                End Get
                Set(ByVal Value As String)
                    dateO = Value
                End Set
            End Property
     
            <XmlElement("Type")>
            Property typeC() As String '   
                Get
                    Return type
                End Get
                Set(ByVal Value As String)
                    type = Value
                End Set
            End Property
     
            <XmlElement("Description")>
            Property descC() As String '   
                Get
                    Return desc
                End Get
                Set(ByVal Value As String)
                    desc = Value
                End Set
            End Property
     
            <XmlElement("Debit")>
            Property debitC() As String '   
                Get
                    Return debit
                End Get
                Set(ByVal Value As String)
                    debit = Value
                End Set
            End Property
     
            <XmlElement("Credit")>
            Property creditC() As String '   
                Get
                    Return credit
                End Get
                Set(ByVal Value As String)
                    credit = Value
                End Set
            End Property
     
            <XmlElement("Solde")>
            Property soldeC() As String '   
                Get
                    Return solde
                End Get
                Set(ByVal Value As String)
                    solde = Value
                End Set
            End Property
    Pour avoir <Budget> comme élément racine, crée une classe budget qui contient la liste d'opérations :

    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
    <XmlRoot("Budget")> ' Pas vraiment utile vu que c'est le nom de la classe, mais comme ça c'est explicite ;)
    Public Class Budget
     
        Private _operations As List(Of operation) = New List(Of operation)()
     
        <XmlElement("Operation")>
        Public Property Operations As List(Of operation)
            Get
                Return _operations
            End Get
            Set(ByVal Value As List(Of operation))
                _operations = Value
            End Set
        End Property
     
    End Class

  6. #26
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    OK d'accord mais maintenant comment ajouter un objet à liste étant donnée quelle est dans une classe ? Enfin c'est un problème de syntaxe quoi.

    J'ai écris ça pour l'instant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dim lst As Budget
     
            lst.Operations().Add(New operation("23/11/2009", "cheque", "Gaz Oil", "100", "0", "900"))
    Mais on me dit que lst est utilisé avant qu'une valeur ne lui soit attribuée


    Même cette ligne lors de la sérialisation change à mon avis même je me suis un peu perdu dans les List(Of operation) je l'avoue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xs = New XmlSerializer(GetType(List(Of operation)))
    Mais j'en doute pas le résultat doit être très pratique car tu n'as pas du me conseiller d'écrire la classe budget pour rien c'est certain.

  7. #27
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par realtux Voir le message
    Mais on me dit que lst est utilisé avant qu'une valeur ne lui soit attribuée
    Ben oui, tu l'as juste déclaré, mais tu ne l'as pas initialisé, donc ça vaut Nothing...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim lst As Budget = New Budget()

    Citation Envoyé par realtux Voir le message
    Même cette ligne lors de la sérialisation change à mon avis même je me suis un peu perdu dans les List(Of operation) je l'avoue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xs = New XmlSerializer(GetType(List(Of operation)))
    Ben là c'est plus une List(Of operation) que tu sérialises, c'est un Budget :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xs = New XmlSerializer(GetType(Budget))

  8. #28
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    OK merci beaucoup je suis vraiment un cas lol c'est nickel.

    Reste plus qu'à savoir si on peut supprimer une ligne et que ça se répercute dans le XML je vais tester.

  9. #29
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Il faut mettre la liste comme DataSource, pas l'objet Budget :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tope.DataSource = lst.ListeO
    Et tu devrais faire attention aux noms que tu choisis pour les classes, membres, variables etc... C'est très important de choisir des noms explicites et d'appliquer une convention, sinon tu vas être complètement perdu quand ton application va commencer à grossir

    - Par exemple, appeler "lst" une variable de type Budget est une mauvaise idée, parce que ça fait croire que c'est une liste ; le budget contient une liste d'opérations, mais ce n'est pas une liste

    - Appeler ListO la liste des opérations n'est pas non plus une bonne idée, parce que ça n'indique pas vraiment de quoi il s'agit... dans le code que je t'avais proposé, je l'avais appelé Operations, ce qui est quand même plus explicite. Le fait que ce soit une liste est relativement évident (Operations, au pluriel), il est par contre plus utile d'indiquer ce qu'elle contient (des opérations).

    D'ailleurs, tu sembles appliquer une sorte de convention de nommage bizarre... d'où sortent ces suffixes O ou C derrière tes noms de champs ou de propriétés ?

    Je développe surtout en C#, donc je ne suis pas très familier des conventions de nommage en VB.NET, mais ce lien devrait te donner des conseils utiles.

  10. #30
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    Ouii pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tope.DataSource = lst.ListeO
    j'avais trouvé juste après avoir posté mon message que j'ai modifié car je me posais des question par rapport à la suppression d'une opération.

    Concernant le nommage de mes variables tu as totalement raison, je sais que les nom doivent être le plus explicites possible pour avoir le moins de commentaire possible(c'est une règle que je connais).
    Ma convention de nommage actuelle résulte de mauvaise habitude pris en cour afin gagner du temps, les noms des variables quant à eux n'en gagnent pas plus de sens.

    Cependant je vais et je doit y remédier car lorsque je passerais devant un jury je ne veux pas qu'il soit aussi exaspérés que toi lol devant ma "Convention de nommage" en effet.

  11. #31
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    J'ai essayé de supprimer une ligne bêtement pour tester avec ce code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    If Me.tope.SelectedRows.Count > 0 AndAlso Not Me.tope.SelectedRows(0).Index = Me.tope.Rows.Count - 1 Then
     
                tope.Rows.RemoveAt(Me.tope.SelectedRows(0).Index)
     
            End If
    Bien évidemment ça ne se répercute pas sur le fichier XML et j'obtiens cette erreur

    Impossible de supprimer des lignes par programme si le DataGridView n'est pas lié à un IBindingList qui prend en charge la notification de modifications et autorise la suppression.

  12. #32
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Bizarre... j'ai fait le test chez moi, et ça marche bien

    Au vu du message d'erreur, tu peux essayer de remplacer la List(Of Operation) par une BindingList(Of Operation) (c'est dans le namespace System.ComponentModel)

  13. #33
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    effectivement il fallait remplacé par "BindingList(Of Operation)" je suis impressionné

    Mais sinon dernière petite précision avant que je ne sérialise, lorsque j' ajoutais une opération via une fenêtre qui récupère les données (date,type..) puis les passes en paramètre dans la fenêtre principal :

    Je calculais le solde en fonction du débit ou crédit (logique) mais aussi en fonction du solde initial (si il à déjà été ajouté ba j'allais chercher le dernier solde dans le XML avec racine.lastchild..) puis je rappelais la procédure d'affichage mais là ça ne fonctionne plus même si j'ai plus besoin d'appeler la procédure d'affichage dans l'ajout.

    Ajout d'une nouvelle opération :

    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
    Public Sub AddNewOPE(ByVal dateN As String, ByVal typeN As String, ByVal descN As String, ByVal debitN As Double, ByVal creditN As Double)
     
            tope.DataSource = Nothing 'Je vide la datasource à chaque fois que j'execute la la procédure d'ajout afin que toutes les lignes s'affiche dans le datagrid
     
            'verifie si une opération a déjà été enregistrée pour définir l'ajout ou non du Solde initiale au Solde
            If nbOPE = 0 Then
                solde = tsoldeI.Text
            Else
                courant = racine.FirstChild
                courant = racine.LastChild
                solde = courant.InnerText
     
            End If
     
     
            If debitN > 0 Then
                solde = solde - debitN
     
            Else
                solde = solde + creditN
     
            End If
     
     
            listeOperations.Operations().Add(New operation(dateN, typeN, descN, debitN, creditN, solde))
            tope.DataSource = listeOperations.Operations()
     
     
            Dim xs As XmlSerializer
            xs = New XmlSerializer(GetType(Budget))
     
            Using sw As New StreamWriter("ope.xml")
                xs.Serialize(sw, listeOperations)
            End Using
     
            courant = racine.FirstChild
            nbOPE = racine.ChildNodes.Count
     
        End Sub
    et ma procédure d'affichage qui se lance en même temps que le programme (lit fichier xml puis le relie à la datasource puis sérialise). Je prend le risque de te la montrer même si tu va sans doute te moquer de la façon dont je l'ai codé lol mais j'ai commencé les collections il y'a quelques jours, je sais qu'il y a des méthodes pour ajouter un élément plus simplement comme "iterator" dont j'en suis pas sur.


    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    Private Sub PrintOPE()
     
     
            Dim _date As String
            Dim _type As String
            Dim _description As String
            Dim _debit As String
            Dim _credit As String
            Dim _solde As String
     
     
            courant = courant.FirstChild
            _date = courant.InnerText
     
            courant = courant.NextSibling
            _type = courant.InnerText
     
            courant = courant.NextSibling
            _description = courant.InnerText
     
            courant = courant.NextSibling
            _debit = courant.InnerText
     
            courant = courant.NextSibling
            _credit = courant.InnerText
     
            courant = courant.NextSibling
            _solde = courant.InnerText
     
     
            listeOperations.Operations().Add(New operation(_date, _type, _description, _debit, _credit, _solde))
     
            courant = courant.ParentNode
     
     
     
            While courant.NextSibling Is Nothing = False
                courant = courant.NextSibling
                courant = courant.FirstChild
                _date = courant.InnerText
     
                courant = courant.NextSibling
                _type = courant.InnerText
     
                courant = courant.NextSibling
                _description = courant.InnerText
     
                courant = courant.NextSibling
                _debit = courant.InnerText
     
                courant = courant.NextSibling
                _credit = courant.InnerText
     
                courant = courant.NextSibling
                _solde = courant.InnerText
     
     
                listeOperations.Operations().Add(New operation(_date, _type, _description, _debit, _credit, _solde))
     
                courant = courant.ParentNode
     
            End While
     
            tope.DataSource = listeOperations.Operations()
     
     
        End Sub

    Ma question est ce que je peux calculer le solde en accédant à la dernière valeur du dernier élément de la liste ? doit-je forcement appeler la procédure d'affichage après l'ajout ?

  14. #34
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par realtux Voir le message
    effectivement il fallait remplacé par "BindingList(Of Operation)" je suis impressionné
    En fait je viens de réaliser pourquoi ça marchait chez moi avec une List (pas BindingList) : je n'avais pas bindé le DataGridView directement sur la liste, je passais pas une BindingSource. Donc si tu préfères utiliser une List (ce que je te conseille), tu peux créer dans ta Form une BindingSource, la choisir comme DataSource du DataGridView (avec le designer), et mettre ta liste comme DataSource de la BindingSource.

    Citation Envoyé par realtux Voir le message
    Ma question est ce que je peux calculer le solde en accédant à la dernière valeur du dernier élément de la liste ? doit-je forcement appeler la procédure d'affichage après l'ajout ?
    Pour accéder au dernier élément de la liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim op As Operation = leBudget.Operations.Item(leBudget.Operations.Count - 1)
    Ou même, si tu es en .NET 3.5 (VS2008), tu peux faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim op As Operation = leBudget.Operations.Last()
    (il faut éventuellement ajouter "Imports System.Linq" s'il n'y est pas déjà)


    Sinon, je vois que tu passes la DataSource du DataGridView à Nothing pour que ça affiche bien les éléments ajoutés. Si tu utilises une BindingList, tu n'as pas besoin de faire ça : la BindingList notifie le DataGridView, qui se rafraichit automatiquement. Si tu utilises une List + BindingSource, tu peux obtenir le même comportement en ajoutant l'élément à la BindingSource plutôt qu'à la List (ça affichera le nouvel élément dans le DGV et ça l'ajoutera à la liste)

  15. #35
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    En fait je viens de réaliser pourquoi ça marchait chez moi avec une List (pas BindingList) : je n'avais pas bindé le DataGridView directement sur la liste, je passais pas une BindingSource. Donc si tu préfères utiliser une List (ce que je te conseille), tu peux créer dans ta Form une BindingSource, la choisir comme DataSource du DataGridView (avec le designer), et mettre ta liste comme DataSource de la BindingSource.
    J'ai bien suivie les étapes mais pour mettre la liste comme datasource : cela se fait il toujours de la même manière ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     MonDGV.DataSource = leBudget.Operations()
    Et puis sur le designer je constate quelque chose de bizar mon ancienne source de donnée (qui apparait en bas avec un petit icône jaune) s' appel "OperationBindingSource", à coter celle que que j'ai crée "BindingSource" dont j'ai sélectionné comme datasouce "test.fenetre1+operation" (dans le petit menu à droite)

  16. #36
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Si tu as déjà une OperationBindingSource, utilise celle là : a priori elle doit être liée au type Operation, ce qui facilite les manipulations dans le designer. Pour affecter la liste comme source de données, ne touche pas au DataGridView. Sa DataSource doit rester OperationBindingSource. A l'exécution, il faut affecter la liste comme source de données de la BindingSource :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OperationBindingSource.DataSource = leBudget.Operations
    (Au fait, les parenthèses ne sont pas nécessaires quand tu fais appel à une propriété. Tu peux les mettre si tu veux, mais à mon avis c'est moins clair parce que ça donne l'impression que c'est une méthode...)

  17. #37
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    Ok d'accord pour les parenthèses moi j'ai l'habitude de coder en Java mais toi qui à l'habitude de coder en C# le VB n'a pas trop l'aire d'avoir de secret pour toi lol.. En même temps tu dois être largement plus expérimenté que moi.

    Sinon c'est OK aussi pour l'accès au dernier élément et comme je voulais le solde j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    leBudget.Operations.Last().Solde
    Mais imaginons que je veuille le total de credit ou debit, c'est possible d'accéder à chacune de ces valeurs de chaque élément à la suite pour les additionner ?

  18. #38
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par realtux Voir le message
    toi qui à l'habitude de coder en C# le VB n'a pas trop l'aire d'avoir de secret pour toi
    En fait quand je me suis mis à .NET, j'ai commencé par VB.NET, mais je suis assez vite passé à C#... je trouve la syntaxe VB.NET trop verbeuse, et d'une manière générale assez "moche" . Mais bon, c'est un avis très personnel... de toutes façons les 2 langages sont à peu près équivalents au niveau des possibilités (enfin y a quand même pas mal de trucs qu'on peut faire en C# et pas en VB ...)

    Citation Envoyé par realtux Voir le message
    Sinon c'est OK aussi pour l'accès au dernier élément et comme je voulais le solde j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    leBudget.Operations.Last().Solde
    Mais imaginons que je veuille le total de credit ou debit, c'est possible d'accéder à chacune de ces valeurs de chaque élément à la suite pour les additionner ?
    La solution la plus évidente est de faire une boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim totalCredit As Decimal = 0
    Dim totalDebit As Decimal = 0
    For Each op As operation in leBudget.Operations
        totalCredit = totalCredit + op.Credit
        totalDebit = totalDebit + op.Debit
    Next
    Par contre, vu que tu as déclaré tous tes champs comme String, tu peux pas faire ça, il faut d'abord les convertir en Decimal (avec CType ou Decimal.Parse par exemple). D'ailleurs, il n'y a aucune raison de les laisser en type String : le DataGridView est parfaitement capable de gérer des types numériques, en plus l'avantage est que si tu tapes un nombre incorrect (avec des lettres par exemples), il te le dit et refuse de valider la cellule.

    Sinon, autre méthode, en utilisant Linq (et toujours en supposant que tu changes le type de tes champs et propriétés)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim totalCredit As Decimal = leBudget.Operations.Sum(Function(op) op.Credit)
    Dim totalDebit As Decimal = leBudget.Operations.Sum(Function(op) op.Debit)

  19. #39
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 93
    Par défaut
    Ouii pour les types biensure que je vais les modifier j'avais oublié mais moi les reels je les met en "double" ça change rien ?

    en plus l'avantage est que si tu tapes un nombre incorrect (avec des lettres par exemples), il te le dit et refuse de valider la cellule
    C'est génial ce DataGridView !! Peut on aussi bloquer toutes les cellules (pas modification dessus) d'une colonne et désactiver un bouton si une ligne n'est pas sélectionné ?

    Et aussi Merci pour cette ligne que tu ma donnée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim op As Operation = leBudget.Operations.Item(leBudget.Operations.Count - 1)
    Parce que je me demandais comment faire recalculer le solde si je modifie un crédit ou débit d'une ligne en avec ça je peu faire Dim op As Operation = leBudget.Operations.Item(leBudget.Operations.Count - 2) je peut récupérer l'avant dernier solde et faire le calcule avec le débit ou crédit modifier. NICKEL c'est trop bien les collections, je vais jeter tous les tableaux à la poubelle

    Pour le reste j'ai utilisé leBudget.Operations.Last() ça tourne je suis sur VS2008 j'ai commencé le VB y'a 2 semaines.

  20. #40
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par realtux Voir le message
    Ouii pour les types biensure que je vais les modifier j'avais oublié mais moi les reels je les met en "double" ça change rien ?
    Le type Decimal est plus adapté pour des sommes d'argent, car sa représentation interne (binaire) ne cause pas d'erreur d'arrondi. Le problème avec un Double est que s'il n'y a pas de représentation exacte de la valeur en binaire, elle est arrondie au plus près. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim d As Double = 8183.23 - 6695.37
    Avec ce code, d ne vaut pas 1487,86 comme prévu, mais 1487,8599999999997. Pour des applications scientifiques par exemple, ce n'est pas forcément gênant, car les valeurs sont rarement exactes de toutes façons. Mais quand il s'agit d'argent, on parle toujours de valeurs exactes et on ne peut pas vraiment se permettre d'arrondir... Surtout qu'en cumulant les erreurs d'arrondi, on peut arriver à des différences significatives. Donc dans ton cas, fais moi confiance, il faut vraiment utiliser Decimal et non Double...


    Citation Envoyé par realtux Voir le message
    C'est génial ce DataGridView !! Peut on aussi bloquer toutes les cellules (pas modification dessus) d'une colonne et désactiver un bouton si une ligne n'est pas sélectionné ?
    Il suffit de mettre la propriété ReadOnly de la colonne à True
    Pour désactiver un bouton quand il n'y a pas de ligne sélectionnée, gère l'évènement SelectionChanged du DGV et vérifie que SelectedRows.Count > 0

    Citation Envoyé par realtux Voir le message
    Et aussi Merci pour cette ligne que tu ma donnée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim op As Operation = leBudget.Operations.Item(leBudget.Operations.Count - 1)
    Parce que je me demandais comment faire recalculer le solde si je modifie un crédit ou débit d'une ligne en avec ça je peu faire Dim op As Operation = leBudget.Operations.Item(leBudget.Operations.Count - 2) je peut récupérer l'avant dernier solde et faire le calcule avec le débit ou crédit modifier. NICKEL
    Euh... ça va pas marcher ton truc... Si tu modifies la première opération et que tu te bases seulement sur les 2 dernières pour recalculer le solde, la modification ne sera pas prise en compte. Il faut recalculer la totalité...

    D'ailleurs je ne suis pas sûr que ce soit une bonne idée de stocker le solde dans chaque opération, ça risque de causer des incohérences par la suite... Ou alors si tu tiens à avoir ça, il faut le recalculer à chaque fois pour toutes les opérations. A mon avis, tu ferais mieux de stocker le solde initial dans la classe Budget, et de recalculer le solde en fonction du solde initial et des crédits/débits de chaque opération

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 4 PremièrePremière 1234 DernièreDernière

Discussions similaires

  1. Réponses: 1
    Dernier message: 07/09/2009, 07h15
  2. sauvegarder le contenu d'un dataGridView dans un fichier Xml
    Par gregcat dans le forum Windows Forms
    Réponses: 1
    Dernier message: 05/02/2008, 18h12
  3. DatagridView et fichier XML
    Par will2taz dans le forum VB.NET
    Réponses: 2
    Dernier message: 26/06/2007, 09h59
  4. Réponses: 2
    Dernier message: 28/09/2006, 09h48
  5. [C#2.0]DatagridView + Chargement fichier XML
    Par chnew dans le forum Windows Forms
    Réponses: 2
    Dernier message: 10/04/2006, 12h35

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