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 :

Aller chercher une propriété dans une DataSource [Débutant]


Sujet :

VB.NET

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut Aller chercher une propriété dans une DataSource
    Bonjour,

    J'ai créé un DataGridView que j'essaye vainement de lier avec des propriété d'un objet, mais cela ne fonctionne qu'à moitié..

    Pour l'exemple, j'ai crée deux classes:
    La classe principale, celle dont je veux lier les membres aux binding

    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Public Class essai
        Public Property mes As New List(Of mesure)
           Public Class mesure
            Public Property acq As New test
            Public Property temperature As Double = 0
        End Class
    End Class
    et la classe test qui est une classe générale
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Public Class test
        Public Property un As Double = 0
        Public Property deux As Double = 0
    End Class
    Dans mon DataGridView, je voudrais 3 colonnes, "un", "deux" et "température", je pensais le faire avec la propriété "DataPropertyName"
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       With DataGridView_KAE
                    .AutoGenerateColumns = True
                    .AutoSize = True
                    .DataSource = essai.mes
                End With
    J'ai donc :
    col1.propertyname="temperature", ca marche très bien.
    Par contre ceux-ci ne fonctionnent pas :
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    col2.propertyname="acq.un"
    col3.propertyname="acq.deux"
    On dirait qu'on ne peut pas aller à une sous propriété.
    Rien de dispo sur MSDN. Si quelqu'un a une solution...

  2. #2
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Hello,

    On ne peut effectivement pas afficher de "sous propriétés" dans les colonnes d'un datagridview.

    Je rencontre régulièrement ce genre de problématique. La solution que j'ai adoptéE est de créer un wrapper anonyme via une requête Linq et d'affecter ce dernier au datagridview.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Merci, je commençais à m'arracher les cheveux en me disant que je n'étais pas doué.

    Comme on arrive à aller chercher une sous-propriété avec les bindings de textbox, je pensais que cela marcherait aussi dans un datagridview, visiblement c'est non.

    J'ai adopté une solution peu élégante, en faisant "remonter" mes sous-propriétés en propriétés simples.

  4. #4
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Je te suggère de tester le wrapper anonyme en linq.

    Ca permet de ne pas toucher à la structure de tes objets pour garder ça propre et c'est quand même vachement utile à connaître.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Je te suggère de tester le wrapper anonyme en linq.
    Possible de me donner un exemple de code?

    Mon besoin n'est pas si compliqué,il faut que je réussisse à redescendre dans les propriétés de mes mesures pour les afficher dans un datagridview. Ma structure se présente en gros comme ça:

    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
     
     Public Class acq
            Public Property prop1 As Double
            Public Property prop2 As Double
        End Class
     
     Public Class calcul
            Public Property mon_calcul As Double
            Public Property acquisition As acq
     End Class
     
        Public Class essai
            Public Property mesures As New bindinglist(Of calcul)
     End Class
     
        Dim mon_objet As New essai
    Dans mon datagridview dgw, je voudrais réussir à faire quelque chose comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    dgw.datasource=mon_objet.mesures
     
     Dim col As New DataGridViewColumn
            With col
                .Name = nom
                .DataPropertyName = ".acquisition.prop1"
                .CellTemplate = cell
                .DefaultCellStyle.Format = "N1"
                .ReadOnly = lecture_seule
            End With
    dgw.columns.add(col)

  6. #6
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Hello,

    Quelque chose dans le genre devrait faire l'affaire (sur base des classes que tu donnes et non testé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Dim wrapper = From c As calcul In mesures
                        Select {.Prop1 = c.acquisition.prop1, .Prop2 = c.acquisition.prop2}
     
    dgw.DataSource = wrapper.ToList

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Ca marche presque bien...
    J'ai maintenant accès à toute les propriété, mais en lecture uniquement. Impossible de rajouter une ligne dans mon datagridview, ou de modifier une valeur.
    Retour à la case départ
    Pas glop...

  8. #8
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Et en ajoutant "New With" entre "Select" et "{" ?

    Mais de toute façon, il faut bien se rendre compte de ce qu'il se passe lorsqu'on utilise linq de cette manière.

    En faisant cela, on crée une liste d'objet anonyme. C'est-à-dire qu'ils n'ont pas de nom (de classe). Tu ne pourras donc pas créer un nouvel objet et l'ajouter au wrapper que j'ai défini dans mon message précédent.

    Tu pourras PEUT-ETRE (jamais essayé), faire qqch du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    wrapper.Add(new with(value1, value2))
    En respectant l'ordre et les types de données de ce que tu as mis dans ta clause Select.

    Pour finir, un détail important. Avec linq en VB.NET, on peut créer des objets anonymes immuables (en read-only) et d'autres non suivant la syntaxe utilisées. Pour ça que je dis de tester avec le New With. Je ne sais plus laquelle fait quoi... Mais tu dois pouvoir trouver l'info facilement sur le net (attention de bien chercher en VB.NET car ces différents types d'objets anonymes n'existent pas en C# il me semble).

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Je ne pense pas que ce soit une méthode adaptée à ma situation.
    Le but est vraiment d'avoir un lien bidirectionnel fort entre un objet et un datagridview. chaque colonne devant aller chercher une propriété ou sous propriété de l'objet.

    Je pense que la solution est à faire du côté du binding.

    Je vais chercher encore sur internet,le souci étant toujours de trouver les bons mots-clés.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Bonjour,

    En passant pas mal de temps sur les forums MS, je pense approcher d'une "bonne" solution.
    Voir cette discussion:

    https://social.msdn.microsoft.com/Fo...msdatacontrols

    Par contre, une truc que je n'arrive pas à faire et qui doit pourtant être tout bête, c'est une fonction qui renvoi la valeur d'une propriété à un index donnée
    class test

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Public Class test
        Public Property prop_general As String
        Public Property liste As BindingList(Of truc)
        Public Class truc
            Public Property prop1 As Double
            Public Property prop2 As Double
        End Class
     
    End Class
     
    dim objet_test as test

    je voudrais réussir à construire une fonction "eval" à qui j'envoi mon objet, la référence de la propriété et l'index dans la liste, et qui me renvoi la valeur de la propriété

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      Public Function eval(obj As Object, prop_name As String, index As Short)
            Dim _index() As Object = {index}
            Dim typ As Type = obj.GetType
            Dim prop As PropertyInfo = typ.GetProperty(prop_name)
            Dim result As Object = prop.GetValue(obj, _index)
            Return rsult
        End Function
    et si je lance eval(object_test.liste,"truc.prop1,1) il me renvoi la valeur:

    objet_test.liste(1).prop1

    Ca a l'air de coincer à la ligne Dim prop As PropertyInfo = typ.GetProperty(prop_name) qui me renvoi "Nothing"

  11. #11
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Fais plutôt une fonction qui renvoie l'objet d'index donné et accède à la propriété dont tu as besoin.

    Ca t'évitera d'avoir à appeler ta fonction 3 fois si tu as besoin de 3 propriétés différentes.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    J'essaye justement de faire ça mais je ne vois pas bien comment marche un getproperty/getvalue


    public function (obj as object, index as short) as object

    return obj.item(index)

    end function

    ne passe pas
    Je ne suis vraiment pas loin, le souci c'est de sauter dans une propriété-enfant d'une liste

    Pardon, pour être un peu plus précis, ca ressemble à ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      Private Sub DGW_pertes_sup_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DGW_pertes_sup.CellFormatting
            If DGW_pertes_sup.Columns(e.ColumnIndex).DataPropertyName.Contains(".") Then
                If Not IsNothing(DGW_pertes_sup.Rows(e.RowIndex).DataBoundItem) Then
                    e.Value = EvaluateValue(DGW_pertes_sup.Rows(e.RowIndex).DataBoundItem, DGW_pertes_sup.Columns(e.ColumnIndex).DataPropertyName, e.RowIndex)
                End If
     
            End If
        End Sub
    Sachant que databounditem me renvoi l'objet lié, datapropertyname me renvoi l'arborescence de ma propriété ".acq.prop1" et rowindex la position dans la liste de mon objet, je n'ai plus qu'à réussir à sortir la valeur

  13. #13
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    A y regarder de plus prêt, j'ai l'impression que t'essaies de faire un truc compliqué (qui impliquerait d'utiliser la reflection si j'dis pas de connerie) au lieu d'utiliser l'index que tu as puisque tu le passes en paramètres...

    Pourquoi ne fais-tu pas liste(index).prop1 (ou prop2 suivant celle dont tu as besoin) directement ?

    Ou alors je n'ai pas compris le besoin.

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Le problème c'est que l'objet, et la propriété ne sont pas toujours les même, et dépendent du DGW et de la de la colonne impliqué.
    En fait, l'objectif est de "tromper" le databind quand il y a besoin de lier des propriété enfant d'un objet.

    Si le datapropertyname contient un "." alors je vais chercher la propriété enfant de l'objet dans la liste à l'index rowindex.

  15. #15
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Je crois que ce serait pas mal que tu donnes du code concret avec ta vraie problématique plutôt que de simplifier avec des classes tests.

    Tu parles notamment de 2 types d'objets dans 2 DGV différents. Montre nous donc la définition de ces 2 types d'objets. On y verra sûrement plus clair (enfin moi en tout cas).

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Je pense que ce n'est pas très compliqué, c'est un problème rencontré par beaucoup d'utilisateurs de DGW, mais les seuls résolutions que j'ai trouvé ne sont pas en VB.net, donc j'essaye d'adapter. De plus, je ne m'exprime sans doute pas très clairement.

    Voici ma classe de base:

    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
    82
    83
    84
    85
    86
    87
     
    Imports System.ComponentModel
    Imports System.Runtime.CompilerServices
     
    Public Class pertes_sup
        Public Property pertes_meca As Double
        Public Property mesures As New BindingList(Of mesure_pertes_sup)
     
        Public Class mesure_pertes_sup
     
            Public Property acq As New acquisition
             Public Property temperature_stator As Double 
            Public ReadOnly Property P_ent As Double
                Get
                    P_ent = acq.I_mot * acq.U_mot
     
                End Get
            End Property
            Public ReadOnly Property pertes_joule_ent As Double 'Pertes joules entrainement
                Get
                    pertes_joule_ent = mon_banc.R_induit * acq.I_mot * acq.I_mot
     
                End Get
            End Property
            Public ReadOnly Property pertes_balais_ent As Double 'Pertes balais entrainement
                Get
                    pertes_balais_ent = 2 * acq.I_mot
     
                End Get
            End Property
            Public ReadOnly Property pertes_meca_ent As Double
                Get
                    pertes_meca_ent = mon_banc.P_meca_ent
     
                End Get
            End Property
            Public ReadOnly Property pertes_ent As Double 'Pertes entrainement
                Get
                    pertes_ent = pertes_meca_CC + pertes_joule_ent + pertes_balais_ent
     
                End Get
            End Property
            Public ReadOnly Property res_stator_chaud As Double
                Get
                    res_stator_chaud = res_froid.R_stator_froid * (235 + temperature_stator) / 235
     
                End Get
            End Property
            Public ReadOnly Property pertes_joule As Double
                Get
                    pertes_joule = 3 * acq.Istator * acq.Istator * res_stator_chaud
                End Get
            End Property
            Public ReadOnly Property pertes_rotor As Double
                Get
                    pertes_rotor = res_froid.rotor_principal_froid * (235 + 40) / (235) * acq.Irotor * acq.Irotor
     
                End Get
            End Property
            Public ReadOnly Property pertes_AE As Double 'Pertes AE (10% pertes rotor)
                Get
                    pertes_AE = 0.1 * pertes_rotor
     
                End Get
            End Property
            Public ReadOnly Property pertes_meca_CC As Double
     
                Get
                    pertes_meca_CC = essai_pertes_sup.pertes_meca
                End Get
            End Property
     
     
            Public ReadOnly Property pertes_CC As Double
                Get
                    pertes_CC = P_ent - pertes_ent
     
                End Get
            End Property
            Public ReadOnly Property pertes_sup As Double
                Get
                    pertes_sup = pertes_CC - pertes_joule - pertes_rotor - pertes_AE
     
                End Get
            End Property
        End Class
    End Class
    et la classe acquisition,

    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
     
    Public Class acquisition
        'Classe définissant une mesure, regroupant l'ensemble des signaux issus de l'acquisition
     
        Public Property U_mot As Double 'tension moteur d'entrainement
        Public Property I_mot As Double 'courant moteur d'entrainement
        Public Property Iex_mot As Double 'courant d'excitation moteur d'entrainement
        Public Property U_rotor As Double 'tension rotor
        Public Property Irotor_mesure As Double 'courant rotor mesuré
        Public Property Irotor As Double
            Get
                Try
                    Irotor = calcul_I_rotor(Istator, Iex)
                Catch ex As Exception
                    Irotor = 0
                End Try
            End Get
            Set(value As Double)
            End Set
        End Property
        Public Property Uex As Double 'tension d'excitation AE
        Public Property Iex As Double 'courant d'excitation AE
        Public Property Iu As Double
        Public Property Iv As Double
        Public Property Iw As Double
        Public Property Istator As Double
        Public Property fi As Double 'fréquence des courant alternateurs
        Public Property Uu As Double
        Public Property Uv As Double
        Public Property Uw As Double
        Public Property Usimple As Double 'moyenne des tensions simples alternateur
        Public Property Uuv As Double
        Public Property Uuw As Double
        Public Property Uvw As Double
        Public Property Ustator As Double
        Public Property fu As Double 'fréquence des tensions alternateurs
        Public Property temperatures As Double()
        Public Property vibrations_RMS As Double()
        Public Property vibrations_H1 As mesure_vibration()
        Public Property vibrations_H2 As mesure_vibration()
    Bon soit, y'a un peu de monde.
    J'ai donc un objet "mes_pertes_sup" construit sur la classe pertes_sup, avec dedans une liste de mesures mes_pertes_sup.mesures ... et je voudrais construire mon datagridview dessus

    Mon gros souci, c'est que dans mon DGW, je veux aller faire un binding sur une propriété "simple" de ma liste ("pertes_balais_ent") par exemple mais aussi un binding sur une propriété enfant (mes_pertes_sup.mesures.acq.istator par exemple)

    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 init_datagrid()
            Try
                With DGW_pertes_sup
                    .AutoGenerateColumns = False
                    .AllowUserToAddRows = True
                    .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders
                    .AllowUserToOrderColumns = False
                    .AllowUserToResizeRows = False
                    .AllowDrop = False
                    .DataSource = essai_pertes_sup.mesures
                End With
                ajouter_colonne(DGW_pertes_sup, "U moteur", "acq.U_mot", False)
                ajouter_colonne(DGW_pertes_sup, "I moteur", "acq.I_mot", False)
                ajouter_colonne(DGW_pertes_sup, "P moteur", "P_ent", True)
                ajouter_colonne(DGW_pertes_sup, "Ri²", "Pertes_joule_ent", True)
                ajouter_colonne(DGW_pertes_sup, "balais", "pertes_balais_ent", True)
                ajouter_colonne(DGW_pertes_sup, "mécaniques", "pertes_meca_CC", True)
                ajouter_colonne(DGW_pertes_sup, "total", "pertes_ent", True)
                ajouter_colonne(DGW_pertes_sup, "Pertes CC", "pertes_CC", True)
                ajouter_colonne(DGW_pertes_sup, "Ri² stator", "pertes_joule", True)
                ajouter_colonne(DGW_pertes_sup, "pertes rotor", "pertes_rotor", True)
                ajouter_colonne(DGW_pertes_sup, "pertes AE", "pertes_AE", True)
                ajouter_colonne(DGW_pertes_sup, "pertes sup", "pertes_sup", True)
                ajouter_colonne(DGW_pertes_sup, "I stator", "acq.Istator", False)
                ajouter_colonne(DGW_pertes_sup, "T stator", "temperature_stator", False)
     
                DGW_pertes_sup.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
     
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
     
        End Sub

    Ca marche bien sur la propriété simple, mais pas sur la propriété enfant. Vu sur internet, c'est un manque dans le DGW, et il n'y a pas de "bonne" solution, il faut travailler sur un détour.

    Le plus "simple" est celui sur lequel je suis en train de m'escrimer, c'est de jouer sur l'événement et sortir directement la valeur, d'où mes questions sur "getproperty" et "gettype"

  17. #17
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Je ne connais pas le business donc j'suis p-e bien à côté de la plaque mais j'ai l'impression que c'est en fait un problème de modélisation. Pcq dans ton dgv, chaque ligne affiche un objet de type perte_sup. Mais chaque objet possède une liste d'acquisition. Du coup, dans la colonne qui affiche une mesure, tu prends laquelle dans la liste d'acquisition ??? Ou alors il te faut 2 dgv. Un pour afficher les objets perte_sup et un autre pour afficher leur acquisition quand tu fais une sélection dans le premier dgv. C'est super louche sinon... Ou alors, j'ai encore rien compris

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Non, ce n'est pas tout à fait ça.

    Dans mon dgv, chaque ligne affiche un objet de type perte sup, OK. Et dans cette objet perte sup il y a une seule acquisition, pas une liste. et dans cette acquisition je veux aller chercher une propriété:

    Alors j'avance hein, j'y suis même presque, j'arrive à tout afficher grâce à l'évènement celleformating, et ma fonction eval:

    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
     
     Private Sub DGW_pertes_sup_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DGW_pertes_sup.CellFormatting
            If DGW_pertes_sup.Columns(e.ColumnIndex).DataPropertyName.Contains(".") Then
                If Not IsNothing(DGW_pertes_sup.Rows(e.RowIndex).DataBoundItem) Then
                    e.Value = EvaluateValue(DGW_pertes_sup.Rows(e.RowIndex).DataBoundItem, DGW_pertes_sup.Columns(e.ColumnIndex).DataPropertyName, e.RowIndex)
                End If
     
            End If
        End Sub
     
        Public Function EvaluateValue(obj As Object, expression As String, index As Object) As Object
     
            Dim liste_propriete() As String = expression.Split(".")
            For i = 0 To liste_propriete.Count - 1
                Dim propriete = obj.GetType.GetProperty(liste_propriete(i))
                If liste_propriete(i) = "Item" Then
                    obj = propriete.GetValue(obj, {index})
                Else : obj = propriete.GetValue(obj)
                End If
            Next
            Return obj
        End Function
    Maintenant le souci, c'est quand je change une valeur de type sous propriété dans mon dgv, il vient ajouter un nouvel élément vide dans ma liste, et qui du coup fait planter les calculs...

  19. #19
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Citation Envoyé par chtinis Voir le message
    Non, ce n'est pas tout à fait ça.

    Dans mon dgv, chaque ligne affiche un objet de type perte sup, OK. Et dans cette objet perte sup il y a une seule acquisition, pas une liste.
    Objection votre honneur !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Imports System.ComponentModel
    Imports System.Runtime.CompilerServices
     
    Public Class pertes_sup
        Public Property pertes_meca As Double
        Public Property mesures As New BindingList(Of mesure_pertes_sup)
     
        Public Class mesure_pertes_sup
             Public Property acq As New acquisition
        End Class
    End Class
    Par transitivité, il y a bien une liste d'acquisition. pertes_sup contient une liste de mesure_pertes_sup qui contient acquisition.
    Ou alors pas besoin de BindingList et tu peux déclarer Public Property mesure As mesure_pertes_sup. Mais cela ne change rien au problème de sous propriété à afficher. Mais au moins, on a quelque chose de logique car je commençais à me demander quoi.

    Voilà comment, personnellement, je résoudrais ton problème. C'est plus ou moins comme cela que je fais dans mes projets de prod. Ce qui varie c'est que je n'utilise jamais l'édition directement dans le dgv. Du coup, jamais besoin d'utiliser l'event CellValidating pour mettre à jour mon objet.

    Deux classes bidons qui présente une structure similaire à la tienne:
    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
    Public Class Person
     
        Public Property Id As Integer
        Public Property Firstname As String
        Public Property Lastname As String
        Public Property Truc As Truc
     
        Public Sub New(i As Integer, f As String, l As String)
            Id = i
            Firstname = f
            Lastname = l
            Truc = New Truc(i)
        End Sub
     
        Public Overrides Function ToString() As String
            Return String.Format("{0} {1} : {2}, {3}, {4}", Firstname, Lastname, Truc.Prop1, Truc.Prop2, Truc.prop3)
        End Function
    End Class
     
    Public Class Truc
        Public Const Const1 As Integer = 1
        Public Const Const2 As Integer = 2
        Public Const Const3 As Integer = 3
     
        Public Property Prop1 As Integer
        Public Property Prop2 As Integer
        Public Property prop3 As Integer
     
        Public Sub New(coef As Integer)
            Prop1 = Const1 * coef
            Prop2 = Const2 * coef
            prop3 = Const3 * coef
        End Sub
    End Class
    Et une winform avec juste un datagridview nommé dgv et un bouton nommé Button1
    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
    82
    83
    Public Class Form1
     
        Private Persons As System.ComponentModel.BindingList(Of Person)
     
        Public Sub New()
     
            ' This call is required by the designer.
            InitializeComponent()
     
            ' Add any initialization after the InitializeComponent() call.
     
            LoadData()
            InitDGV()
            DisplayData()
        End Sub
     
        Private Sub LoadData()
            Persons = New System.ComponentModel.BindingList(Of Person)
            Persons.Add(New Person(0, "machin", "bidule"))
            Persons.Add(New Person(1, "truc", "muche"))
            Persons.Add(New Person(2, "patate", "zak"))
        End Sub
     
        Private Sub InitDGV()
            With dgv
                .AutoGenerateColumns = False
                .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
     
                Dim index As Integer
                With .Columns
                    index = .Add("dgvcId", "Id")
                    .Item(index).DataPropertyName = "Id"
                    .Item(index).Visible = False
     
                    index = .Add("dgvcFirstname", "Firstname")
                    .Item(index).DataPropertyName = "Firstname"
     
                    index = .Add("dgvcLastname", "Lastname")
                    .Item(index).DataPropertyName = "Lastname"
     
                    index = .Add("dgvcProp1", "Prop1")
                    .Item(index).DataPropertyName = "Prop1"
     
                    index = .Add("dgvcProp2", "Prop2")
                    .Item(index).DataPropertyName = "Prop2"
     
                    index = .Add("dgvcProp3", "Prop3")
                    .Item(index).DataPropertyName = "Prop3"
                End With
            End With
        End Sub
     
        Private Sub DisplayData()
            Dim wrapper = From p As Person In Persons
                          Select New With {.Id = p.Id, .Firstname = p.Firstname, .Lastname = p.Lastname, .Prop1 = p.Truc.Prop1, .Prop2 = p.Truc.Prop2, .Prop3 = p.Truc.prop3}
     
            dgv.DataSource = wrapper.ToList
        End Sub
     
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            For Each p As Person In Persons
                MsgBox(p.ToString)
            Next
        End Sub
     
        Private Sub DataGridView1_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs) Handles dgv.CellValidating
            Dim person As Person = (From p As Person In Persons
                                    Where p.Id = CInt(dgv.Rows(e.RowIndex).Cells("dgvcId").Value)
                                    Select p).FirstOrDefault
            Select Case dgv.Columns(e.ColumnIndex).Name
                Case "dgvcFirstname"
                    person.Firstname = e.FormattedValue
                Case "dgvcLastname"
                    person.Lastname = e.FormattedValue
                Case "dgvcProp1"
                    person.Truc.Prop1 = e.FormattedValue
                Case "dgvcProp2"
                    person.Truc.Prop2 = e.FormattedValue
                Case "dgvcProp3"
                    person.Truc.prop3 = e.FormattedValue
            End Select
        End Sub
    End Class
    Au lancement, ça crée 3 objets et les affiche dans la grille. Tu peux éditer ce que tu veux dans la grille. Le bouton fait simplement une boucle sur la liste d'objet pour en afficher le contenu. Tu verras que le contenu correspond bien à ce qui est mis dans la grille.

    Par contre avec ce système, vu qu'il s'agit d'objet anonyme dans la grille, interdiction d'en ajouter de nouveau. Il te faut alors un petit formulaire de création tout simple. Où tu pourras faire ta validation de données beaucoup plus proprement que si tu créais ton objet directement dans le dgv.

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    C'était ma solution de départ, mais mes utilisateurs y ont mis leur grain de sel...

    Tout le souci étant qu'ils veulent pouvoir récupérer automatiquement les acquisitions, mais aussi pouvoir les modifier, et en créer une de toute pièce.
    Et comme j'ai pas loin de 20 dgw, je cherche une méthode qui m'évite de multiplier les classes et les formulaires.

    Là où j'en suis, tout va bien pour l'affichage, tout le monde a la bonne valeur.
    Me reste à gérer l'édition de la même manière, je dois juste trouver le bon évènement sur lequel appliquer ma fonction.

    j'en suis à travailler sur CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs) Handles DGW_pertes_sup.CellValidating

    Ca marche bien, mon seul souci est maintenant d'affecter la valeur que je viens de récupérer (e.formattedvalue) à la propriété de mon objet.
    Je pensais utiliser la même méthode, mais en fait tout ce que j'ai c'est une "image" de mon objet, et je ne pointe pas réellement vers la propriété, donc je ne la modifie pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     Public Sub forcevalue(obj As Object, expression As String, index As Object, value As Object)
            Dim liste_propriete() As String = expression.Split(".")
            Dim propriete As PropertyInfo
            For i = 0 To liste_propriete.Count - 1
                propriete = obj.GetType.GetProperty(liste_propriete(i))
                If liste_propriete(i) = "Item" Then
                    obj = propriete.GetValue(obj, {index})
                Else : obj = propriete.GetValue(obj)
                End If
            Next
            obj = value
        End Sub
    Ce qui est rageant, c'est que j'ai tout les éléments, l'objet obj, le chemin complet de la propriété,expression et la valeur à donner value, il faut juste que je réussisse à coder
    obj.expression=value

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 10
    Dernier message: 01/12/2010, 08h26
  2. Eval d'une propriété d'une classe dans une classe
    Par bizet dans le forum ASP.NET
    Réponses: 4
    Dernier message: 28/10/2008, 09h43
  3. [POO] dans une classe, appeler une fonction dans une méthode
    Par arnaudperfect dans le forum Langage
    Réponses: 3
    Dernier message: 26/08/2007, 23h04
  4. Envoyer une formulaire dans une page dans une Frame
    Par zooffy dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 29/06/2007, 10h13
  5. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 13h48

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