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 :

Update Databindings sur objet perso [Débutant]


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Technicien de bureau d etude
    Inscrit en
    Avril 2011
    Messages
    111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Technicien de bureau d etude
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 111
    Par défaut Update Databindings sur objet perso
    Bonjour à tous,

    Je cherche a réaliser un databinding sur un objet perso.

    Mon problème est le suivant : Lorsque je change mes valeurs par du code (en ouvrant un fichier perso) l'affichage dans mon Control (Datagridview) ne se met pas à jour

    J'ai essayé en implémentant mais rien n'y fait

    Ci dessous mes bouts de codes :

    Chargement de la page :

    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
        Public MaStackup As New StackupClass
     
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     
            Dim MyFile As New OpenFileDialog
            Dim Rep = MyFile.ShowDialog
     
            If File.Exists(MyFile.FileName) Then
     
                Dim myFileStream As Stream = File.OpenRead(MyFile.FileName)
                Dim deserializer As New BinaryFormatter()
                MaStackup = CType(deserializer.Deserialize(myFileStream), StackupClass)
                myFileStream.Close()
            End If
     
            DataGridView1.DataBindings.Add(New Binding("Datasource", MaStackup, "Dimensions") With {.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged})
     
        End Sub
    Ouverture d'un nouveau fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
       Private Sub ButtonOuvrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOuvrir.Click
     
            Dim MyFile As New OpenFileDialog
            Dim Rep = MyFile.ShowDialog
     
            If File.Exists(MyFile.FileName) Then
                Dim myFileStream As Stream = File.OpenRead(MyFile.FileName)
                Dim deserializer As New BinaryFormatter()
                MaStackup = CType(deserializer.Deserialize(myFileStream), StackupClass)
                myFileStream.Close()
            End If
     
        End Sub
    Objet StackupClass :

    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
    <Serializable()> Public Class StackupClass
     
        Implements INotifyPropertyChanged
     
        <NonSerialized()> Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
     
        Private _Dimensions As StackupDimensions
        Public Property Dimensions() As StackupDimensions
            Get
                Return _Dimensions
            End Get
            Set(ByVal value As StackupDimensions)
                _Dimensions = value
            End Set
        End Property
     
     
        Private Sub OnPropertyChanged(ByVal propertyName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
        End Sub
     
     
     
     
    End Class
    Objets StackupDimensions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <Serializable()> Public Class StackupDimensions
        Inherits List(Of StackupDimension)
        Implements INotifyPropertyChanged
     
        Private Sub OnPropertyChanged(ByVal propertyName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
        End Sub
     
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    End Class
    Objets StackupDimension :

    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
    <Serializable()> Public Class StackupDimension
        Implements INotifyPropertyChanged
        Private Sub OnPropertyChanged(ByVal propertyName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
        End Sub
     
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
     
        Private _Name As String
        Private _NominalValue As Decimal
     
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
     
        Public Property NominalValue() As Decimal
            Get
                Return _NominalValue
            End Get
            Set(ByVal value As Decimal)
                _NominalValue = value
            End Set
        End Property
    End Class
    Merci d'avance pour vos lumières !

  2. #2
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour a.floranc
    En winform tu n'as pas besoin d' implementer l'interface INotifyPropertyChanged.

    Car elle est intrinseque au DataBindings comme tu le vois bien dans Control.DataBindings.....(son mecanisme fait une maj dans les 2 sens).....
    1/ N'oublie pas à chaque ajout d'un binding à un control de "clearer" son binding existant sinon tu as un exception ......
    2/de qualifier les chemins d'acces complet pour proprietes bindees dans datasource......en cas d'imbrication propfonde de tes class...

    voici ton simple code revu :
    class .vb :
    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
     
    <Serializable()>
    Public Class StackupClass
        'initialise ta liste svp
        Private _Dimensions As StackupDimensions = New StackupDimensions
        Public Property Dimensions() As StackupDimensions
            Get
                Return _Dimensions
            End Get
            Set(ByVal value As StackupDimensions)
                _Dimensions = value
            End Set
        End Property
    End Class
    <Serializable()>
    Public Class StackupDimensions
        Inherits List(Of StackupDimension)
    End Class
    <Serializable()>
    Public Class StackupDimension
        Private _Name As String
        Private _NominalValue As Decimal
     
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
     
        Public Property NominalValue() As Decimal
            Get
                Return _NominalValue
            End Get
            Set(ByVal value As Decimal)
                _NominalValue = value
            End Set
        End Property
     
    End Class
    le code du form (fais d'abord un test de serialization avec le bouton btnTestSerialize) et le dgv qui s'affiche correctement au chargement du form:
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Binary
     
    Public Class Form1
        Public MaStackup As New StackupClass
        Public monFichier As String = "stack.stk"
     
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim dlgOpen As New OpenFileDialog
            dlgOpen.Filter = "Files(*.stk)|*.stk"
            Dim Rep = dlgOpen.ShowDialog
     
            If dlgOpen.FileName.Length = 0 Then Return
     
            Dim myFileStream As Stream = File.OpenRead(dlgOpen.FileName)
            Dim deserializer As New BinaryFormatter()
            MaStackup = CType(deserializer.Deserialize(myFileStream), StackupClass)
            myFileStream.Close()
     
            '--------Clear des  DataBindings courants sinon un exception "fire"------
     
            DataGridView1.DataBindings.Clear()
            DataGridView1.DataBindings.Add(New Binding("Datasource", MaStackup, "Dimensions") With {.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged})
            txtName.DataBindings.Clear()
            txtName.DataBindings.Add(New Binding("Text", MaStackup.Dimensions, "Name", True,
      DataSourceUpdateMode.OnPropertyChanged, ""))
            '--------Clear
            txtNominalValue.DataBindings.Clear()
            '--------Clear
            txtNominalValue.DataBindings.Add(New Binding("Text", MaStackup.Dimensions, "NominalValue", True,
      DataSourceUpdateMode.OnPropertyChanged, 0.0))
        End Sub
     
        Private Sub ButtonOuvrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOuvrir.Click
            Dim dlgOpen As New OpenFileDialog
            dlgOpen.Filter = "Files(*.stk)|*.stk"
            Dim Rep = dlgOpen.ShowDialog
            If Rep = DialogResult.OK Then
                If dlgOpen.FileName.Length = 0 Then Return
                Dim fs As Stream = File.OpenRead(dlgOpen.FileName)
                Dim deserializer As New BinaryFormatter()
                MaStackup = CType(deserializer.Deserialize(fs), StackupClass)
                fs.Close()
            End If
            '--------Clear des  DataBindings 
     
            DataGridView1.DataBindings.Clear()
            DataGridView1.DataBindings.Add(New Binding("Datasource", MaStackup, "Dimensions") With {.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged})
     
            '2 controls text pour voir la synchronisation
            '--------Clear
            txtName.DataBindings.Clear()
            txtName.DataBindings.Add(New Binding("Text", MaStackup.Dimensions, "Name", True,
       DataSourceUpdateMode.OnPropertyChanged, ""))
            '--------Clear
            txtNominalValue.DataBindings.Clear()
            txtNominalValue.DataBindings.Add(New Binding("Text", MaStackup.Dimensions, "NominalValue", True,
      DataSourceUpdateMode.OnPropertyChanged, 0.0))
        End Sub
        'serialize notre fichier test 
        Private Sub btnTestSerialize_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTestSerialize.Click
            Dim stackTest As StackupClass = GetDataTest()
            Dim dlgSave As New SaveFileDialog
            Dim Rep = dlgSave.ShowDialog
            If Rep = DialogResult.OK Then
                dlgSave.FileName = monFichier
     
                Dim fs As Stream = File.OpenWrite(dlgSave.FileName)
                Dim serializer As New BinaryFormatter()
                serializer.Serialize(fs, stackTest)
                fs.Close()
            End If
     
        End Sub
        Private Function GetDataTest() As StackupClass
            Dim testStackClass As StackupClass = New StackupClass
     
            Dim std As StackupDimension
            Dim rnd As Random = New Random(DateTime.Now.Second)
            For index As Integer = 1 To 10
                std = New StackupDimension
                std.Name = "Pile" + (index * 100).ToString
                std.NominalValue = Convert.ToDecimal(100 * rnd.NextDouble())
                testStackClass.Dimensions.Add(std)
            Next
            Return testStackClass
        End Function
     
     
        'validation virgule  decimal "francais'
        Private Sub txtNominalValue_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtNominalValue.TextChanged
            Dim result As Decimal = 0.0
            If Not Decimal.TryParse(txtNominalValue.Text, result) Then
                txtNominalValue.Clear()
                MessageBox.Show("need french decimal  value...")
            End If
            DataGridView1.Refresh()
        End Sub
     
     
    End Class
    bon code...........

  3. #3
    Membre confirmé
    Homme Profil pro
    Technicien de bureau d etude
    Inscrit en
    Avril 2011
    Messages
    111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Technicien de bureau d etude
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 111
    Par défaut
    Merci MABROUKI pour ton retour, ton code m'a bien aider mais il reste encore une zone d'ombre pour moi.

    En effet je pensait que lorsque je faisait un databinding sur un objet je n'avais pas besoin de le refaire lors du changement de l'objet.

    Par contre en allant un peu plus loin dans mon code j'ai voulu calculer automatiquement une somme de valeur à partir de ma liste de "StackupDimensions", en gros prendre tout les items de la liste et additionner leurs propriété "NominaleValue", valeur qui est elle même stockée dans l'objet StackupClass.

    Malheureusement à ce moment là la valeur est bien calculée dans l'objet, mais ne se met pas à jour dans le texte box prévu à cette effet.

    Finalement dés que je manipule l'objet par le code, aucune mise à jour des Control ne se passe ! Cela me parait bizarre, mais je pense avoir loupé un bout !

    Ma nouvelle class pour mémoire :

    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
     
    Imports System.ComponentModel
     
    <Serializable()> Public Class StackupClass
        'initialise ta liste svp
        Private _Nominal As Decimal
        Private WithEvents _Dimensions As New BindingList(Of StackupDimension)
     
        Public Property Dimensions() As BindingList(Of StackupDimension)
            Get
                Return _Dimensions
            End Get
            Set(ByVal value As BindingList(Of StackupDimension))
                _Dimensions = value
            End Set
        End Property
     
     
        Public Property Nominal() As Decimal
            Get
                Return _Nominal
            End Get
            Set(ByVal value As Decimal)
                _Nominal = value
            End Set
        End Property
     
        Private Sub Dimensions_ListChanged(ByVal sender As Object, ByVal e As ListChangedEventArgs) Handles _Dimensions.ListChanged
            If e.ListChangedType = ListChangedType.ItemChanged Then
                If e.PropertyDescriptor IsNot Nothing AndAlso e.PropertyDescriptor.Name = "NominalValue" Then
                    Dim TempValue As Decimal = 0
                    For Each Child As StackupDimension In _Dimensions
                        TempValue = TempValue + Child.NominalValue
                    Next
                    _Nominal = TempValue
                End If
            End If
        End Sub
     
    End Class
     
     
    <Serializable()> Public Class StackupDimension
        Implements INotifyPropertyChanged
     
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
     
        Private _Name As String
        Private _NominalValue As Decimal
     
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
     
        Public Property NominalValue() As Decimal
            Get
                Return _NominalValue
            End Get
            Set(ByVal value As Decimal)
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NominalValue"))
                _NominalValue = value
            End Set
        End Property
     
    End Class

  4. #4
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    rebonjour a.floranc

    J'avais mal compris en fait la question.Je pensais que le souci etait dans la liaison entre control et objet data....
    En fait tu es sur la bonne direction car il faut implementer l'interface l'
    INotifyPropertyChanged dans :
    - base StackupDimension(base class)
    - StackupClass(Super Inherited Class)
    - deriver StackupDimensions bien sur de BindingList(Of)
    L'implementation de l'interface INotifyPropertyChanged c'est du "boilerplate code" ou code repetetif.....
    Faire attention à l'implementation du StackupDimension(base) qui doit disposer d'un ctor public sans parametre ce qui permet d'ajouter un element non initialise interactivement dans le dgv......

    De plus vu la seriliazation il faut reset le contenu de StackupClass en rebouclant sur les "items" pour garder la notification aux controls....

    code .vb des 3 class revu:
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    Imports System.ComponentModel
    'Base Class
    <Serializable()> _
    Public Class StackupDimension
        'AJOUT : Interface INotifyPropertyChanged
        Implements INotifyPropertyChanged
        'AJOUT : ctor sans parametre
        'pour ajouter interactivement de nouveaux record dans dgv
        Public Sub New()
        End Sub
     
        Public Sub New(ByVal n As String, ByVal v As Decimal)
            'AJOUT :call base class
            MyBase.new()
            Name = n
            NominalValue = v
        End Sub
        Private m_Name As String
        Public Property Name() As String
            Get
                Return m_Name
            End Get
            Set(ByVal value As String)
                m_Name = value
                'AJOUTER la notification
                NotifyPropertyChanged("Name")
            End Set
        End Property
        Private m_NominalValue As Decimal
        Public Property NominalValue() As Decimal
            Get
                Return m_NominalValue
            End Get
            Set(ByVal value As Decimal)
                m_NominalValue = value
                'AJOUTER la notification
                NotifyPropertyChanged("NominalValue")
            End Set
        End Property
        'AJOUT simple implementation
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
        Private Sub NotifyPropertyChanged(ByVal propName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
        End Sub
    End Class
    'Inherited Class list
    <Serializable()> _
    Public Class StackupDimensions
        'AJOUT inherits du bon type de list(of)
        Inherits BindingList(Of StackupDimension)
        Public Sub New()
            Me.AllowEdit = True
            Me.AllowNew = True
            Me.AllowRemove = True
            Me.RaiseListChangedEvents = True
        End Sub
    End Class
    'Super Inherited Class
    <Serializable()> _
    Public Class StackupClass
        'AJOUT : Interface INotifyPropertyChanged
        Implements INotifyPropertyChanged
        Public Sub New()
            Nominal = 0.0
            Dimensions = New StackupDimensions
            'AJOUT Handler
            AddHandler Me.Dimensions.ListChanged, AddressOf Dimensions_ListChanged
        End Sub
     
        Private m_Nominal As Decimal
        Public Property Nominal() As Decimal
            Get
                Return m_Nominal
            End Get
            Set(ByVal value As Decimal)
                m_Nominal = value
                'AJOUTER la notification
                NotifyPropertyChanged("Nominal")
            End Set
        End Property
        Private WithEvents m_Dimensions As StackupDimensions
        Public Property Dimensions() As StackupDimensions
            Get
                Return m_Dimensions
            End Get
            Set(ByVal value As StackupDimensions)
                m_Dimensions = value
                'AJOUTER la notification
                NotifyPropertyChanged("Dimensions")
     
            End Set
        End Property
     
     
        'AJOUT simple implementation
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
        Private Sub NotifyPropertyChanged(ByVal propName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
     
        End Sub
        Private Sub Dimensions_ListChanged(ByVal sender As Object, ByVal e As ListChangedEventArgs)
     
            If e.ListChangedType = ListChangedType.ItemAdded Or
               e.ListChangedType = ListChangedType.ItemDeleted Or
             e.ListChangedType = ListChangedType.ItemChanged Then
     
                '-----------appel à maj total--------------
                UpdateTotal()
            End If
        End Sub
        Private Sub UpdateTotal()
     
            Nominal = 0.0
            For Each item In Dimensions
                Nominal += item.NominalValue
            Next
        End Sub
     
    End Class
    code .vb du winform deja communique simplifie avec un label maj si -interactivement-:
    -on supprime un element du dgv
    -on ajoute un element ""
    -si on change la valeur d'un prop NomimalValue
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Binary
     
    Public Class Form1
        Public MaStackup As New StackupClass
        Public monFichier As String = "stack.stk"
     
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            '     Dim dlgOpen As New OpenFileDialog
            '     dlgOpen.Filter = "Files(*.stk)|*.stk"
            '     Dim Rep = dlgOpen.ShowDialog
     
            '     If dlgOpen.FileName.Length = 0 Then Return
     
            '     Dim myFileStream As Stream = File.OpenRead(dlgOpen.FileName)
            '     Dim deserializer As New BinaryFormatter()
            '     MaStackup = CType(deserializer.Deserialize(myFileStream), StackupClass)
            '     myFileStream.Close()
     
            '     '--------Clear des  DataBindings courants sinon un exception "fire"------
     
            '     DataGridView1.DataBindings.Clear()
            '     DataGridView1.DataBindings.Add(New Binding("DataSource", MaStackup, "Dimensions", True,
            '                                        DataSourceUpdateMode.OnPropertyChanged, Nothing))
            '     '--------Clear DataBindings 
            '     lblNominal.DataBindings.Clear()
            '     lblNominal.DataBindings.Add(New Binding("Text", MaStackup, "Nominal", True, _
            'DataSourceUpdateMode.OnPropertyChanged, ""))
     
     
     
        End Sub
     
        Private Sub ButtonOuvrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOuvrir.Click
            Dim dlgOpen As New OpenFileDialog
            dlgOpen.Filter = "Files(*.stk)|*.stk"
            Dim Rep = dlgOpen.ShowDialog
            If Rep = DialogResult.OK Then
                If dlgOpen.FileName.Length = 0 Then Return
                Dim fs As Stream = File.OpenRead(dlgOpen.FileName)
                Dim deserializer As New BinaryFormatter()
                MaStackup = CType(deserializer.Deserialize(fs), StackupClass)
                fs.Close()
            End If
            'RESET  des "items" ou rechargement
            Dim resetedStackupClass As StackupClass = New StackupClass
            MaStackup = resetData(MaStackup, resetedStackupClass)
     
            '--------Clear   DataBindings 
            DataGridView1.DataBindings.Clear()
            DataGridView1.DataBindings.Add(New Binding("DataSource", MaStackup, "Dimensions", True,
                                               DataSourceUpdateMode.OnPropertyChanged, Nothing))
     
     
            '--------un label binde à prop Nominal 
            '--------Clear DataBindings 
            lblNominal.DataBindings.Clear()
            lblNominal.DataBindings.Add(New Binding("Text", MaStackup, "Nominal", True,
                                                       DataSourceUpdateMode.OnPropertyChanged, ""))
     
     
        End Sub
        Private Function resetData(ByVal MaStackup As StackupClass, ByVal resetStackupClass As StackupClass) As StackupClass
            For Each item As StackupDimension In MaStackup.Dimensions
                resetStackupClass.Dimensions.Add(item)
     
            Next
            Return resetStackupClass
        End Function
        'serialize notre fichier test 
        Private Sub btnTestSerialize_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTestSerialize.Click
            Dim stackTest As StackupClass = GetDataTest()
            Dim dlgSave As New SaveFileDialog
            Dim Rep = dlgSave.ShowDialog
            If Rep = DialogResult.OK Then
                dlgSave.FileName = monFichier
     
                Dim fs As Stream = File.OpenWrite(dlgSave.FileName)
                Dim serializer As New BinaryFormatter()
                serializer.Serialize(fs, stackTest)
                fs.Close()
            End If
            stackTest = Nothing
        End Sub
        Private Function GetDataTest() As StackupClass
            Dim testStackClass As StackupClass = New StackupClass
     
            Dim std As StackupDimension
            Dim rnd As Random = New Random(DateTime.Now.Second)
            For index As Integer = 1 To 4
                std = New StackupDimension
                std.Name = "Pile" + (index * 100).ToString
                Dim number As Decimal = Convert.ToDecimal(100 * rnd.NextDouble())
                std.NominalValue = Decimal.Round(number, 0)
                testStackClass.Dimensions.Add(std)
            Next
            Return testStackClass
        End Function
     
    End Class
    bon code......................

  5. #5
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    rebonjour a.floranc

    J'avais mal compris en fait la question.Je pensais que le souci etait dans la liaison entre control et objet data....
    En fait tu es sur la bonne direction car il faut implementer l'interface l'
    INotifyPropertyChanged dans :
    - base StackupDimension(base class)
    - StackupClass(Super Inherited Class)
    - deriver StackupDimensions bien sur de BindingList(Of)
    L'implementation de l'interface INotifyPropertyChanged c'est du "boilerplate code" ou code repetetif.....
    Faire attention à l'implementation du StackupDimension(base) qui doit disposer d'un ctor public sans parametre ce qui permet d'ajouter un element non initialise interactivement dans le dgv......

    De plus vu la serialiazation il faut reseter le contenu de StackupClass en rebouclant sur les "items" pour garder la notification aux controls....

    code .vb des 3 class revu:
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    Imports System.ComponentModel
    'Base Class
    <Serializable()> _
    Public Class StackupDimension
        'AJOUT : Interface INotifyPropertyChanged
        Implements INotifyPropertyChanged
        'AJOUT : ctor sans parametre
        'pour ajouter interactivement de nouveaux record dans dgv
        Public Sub New()
        End Sub
     
        Public Sub New(ByVal n As String, ByVal v As Decimal)
            'AJOUT :call base class
            MyBase.new()
            Name = n
            NominalValue = v
        End Sub
        Private m_Name As String
        Public Property Name() As String
            Get
                Return m_Name
            End Get
            Set(ByVal value As String)
                m_Name = value
                'AJOUTER la notification
                NotifyPropertyChanged("Name")
            End Set
        End Property
        Private m_NominalValue As Decimal
        Public Property NominalValue() As Decimal
            Get
                Return m_NominalValue
            End Get
            Set(ByVal value As Decimal)
                m_NominalValue = value
                'AJOUTER la notification
                NotifyPropertyChanged("NominalValue")
            End Set
        End Property
        'AJOUT simple implementation
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
        Private Sub NotifyPropertyChanged(ByVal propName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
        End Sub
    End Class
    'Inherited Class list
    <Serializable()> _
    Public Class StackupDimensions
        'AJOUT inherits du bon type de list(of)
        Inherits BindingList(Of StackupDimension)
        Public Sub New()
            Me.AllowEdit = True
            Me.AllowNew = True
            Me.AllowRemove = True
            Me.RaiseListChangedEvents = True
        End Sub
    End Class
    'Super Inherited Class
    <Serializable()> _
    Public Class StackupClass
        'AJOUT : Interface INotifyPropertyChanged
        Implements INotifyPropertyChanged
        Public Sub New()
            Nominal = 0.0
            Dimensions = New StackupDimensions
            'AJOUT Handler
            AddHandler Me.Dimensions.ListChanged, AddressOf Dimensions_ListChanged
        End Sub
     
        Private m_Nominal As Decimal
        Public Property Nominal() As Decimal
            Get
                Return m_Nominal
            End Get
            Set(ByVal value As Decimal)
                m_Nominal = value
                'AJOUTER la notification
                NotifyPropertyChanged("Nominal")
            End Set
        End Property
        Private WithEvents m_Dimensions As StackupDimensions
        Public Property Dimensions() As StackupDimensions
            Get
                Return m_Dimensions
            End Get
            Set(ByVal value As StackupDimensions)
                m_Dimensions = value
                'AJOUTER la notification
                NotifyPropertyChanged("Dimensions")
     
            End Set
        End Property
     
     
        'AJOUT simple implementation
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
        Private Sub NotifyPropertyChanged(ByVal propName As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
     
        End Sub
        Private Sub Dimensions_ListChanged(ByVal sender As Object, ByVal e As ListChangedEventArgs)
     
            If e.ListChangedType = ListChangedType.ItemAdded Or
               e.ListChangedType = ListChangedType.ItemDeleted Or
             e.ListChangedType = ListChangedType.ItemChanged Then
     
                '-----------appel à maj total--------------
                UpdateTotal()
            End If
        End Sub
        Private Sub UpdateTotal()
     
            Nominal = 0.0
            For Each item In Dimensions
                Nominal += item.NominalValue
            Next
        End Sub
     
    End Class
    code .vb du winform deja communique simplifie avec un label maj si -interactivement-:
    -on supprime un element du dgv
    -on ajoute un element ""
    -si on change la valeur d'un prop NomimalValue
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Binary
     
    Public Class Form1
        Public MaStackup As New StackupClass
        Public monFichier As String = "stack.stk"
     
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            '     Dim dlgOpen As New OpenFileDialog
            '     dlgOpen.Filter = "Files(*.stk)|*.stk"
            '     Dim Rep = dlgOpen.ShowDialog
     
            '     If dlgOpen.FileName.Length = 0 Then Return
     
            '     Dim myFileStream As Stream = File.OpenRead(dlgOpen.FileName)
            '     Dim deserializer As New BinaryFormatter()
            '     MaStackup = CType(deserializer.Deserialize(myFileStream), StackupClass)
            '     myFileStream.Close()
     
            '     '--------Clear des  DataBindings courants sinon un exception "fire"------
     
            '     DataGridView1.DataBindings.Clear()
            '     DataGridView1.DataBindings.Add(New Binding("DataSource", MaStackup, "Dimensions", True,
            '                                        DataSourceUpdateMode.OnPropertyChanged, Nothing))
            '     '--------Clear DataBindings 
            '     lblNominal.DataBindings.Clear()
            '     lblNominal.DataBindings.Add(New Binding("Text", MaStackup, "Nominal", True, _
            'DataSourceUpdateMode.OnPropertyChanged, ""))
     
     
     
        End Sub
     
        Private Sub ButtonOuvrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOuvrir.Click
            Dim dlgOpen As New OpenFileDialog
            dlgOpen.Filter = "Files(*.stk)|*.stk"
            Dim Rep = dlgOpen.ShowDialog
            If Rep = DialogResult.OK Then
                If dlgOpen.FileName.Length = 0 Then Return
                Dim fs As Stream = File.OpenRead(dlgOpen.FileName)
                Dim deserializer As New BinaryFormatter()
                MaStackup = CType(deserializer.Deserialize(fs), StackupClass)
                fs.Close()
            End If
            'RESET  des "items" ou rechargement
            Dim resetedStackupClass As StackupClass = New StackupClass
            MaStackup = resetData(MaStackup, resetedStackupClass)
     
            '--------Clear   DataBindings 
            DataGridView1.DataBindings.Clear()
            DataGridView1.DataBindings.Add(New Binding("DataSource", MaStackup, "Dimensions", True,
                                               DataSourceUpdateMode.OnPropertyChanged, Nothing))
     
     
            '--------un label binde à prop Nominal 
            '--------Clear DataBindings 
            lblNominal.DataBindings.Clear()
            lblNominal.DataBindings.Add(New Binding("Text", MaStackup, "Nominal", True,
                                                       DataSourceUpdateMode.OnPropertyChanged, ""))
     
     
        End Sub
        Private Function resetData(ByVal MaStackup As StackupClass, ByVal resetStackupClass As StackupClass) As StackupClass
            For Each item As StackupDimension In MaStackup.Dimensions
                resetStackupClass.Dimensions.Add(item)
     
            Next
            Return resetStackupClass
        End Function
        'serialize notre fichier test 
        Private Sub btnTestSerialize_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTestSerialize.Click
            Dim stackTest As StackupClass = GetDataTest()
            Dim dlgSave As New SaveFileDialog
            Dim Rep = dlgSave.ShowDialog
            If Rep = DialogResult.OK Then
                dlgSave.FileName = monFichier
     
                Dim fs As Stream = File.OpenWrite(dlgSave.FileName)
                Dim serializer As New BinaryFormatter()
                serializer.Serialize(fs, stackTest)
                fs.Close()
            End If
            stackTest = Nothing
        End Sub
        Private Function GetDataTest() As StackupClass
            Dim testStackClass As StackupClass = New StackupClass
     
            Dim std As StackupDimension
            Dim rnd As Random = New Random(DateTime.Now.Second)
            For index As Integer = 1 To 4
                std = New StackupDimension
                std.Name = "Pile" + (index * 100).ToString
                Dim number As Decimal = Convert.ToDecimal(100 * rnd.NextDouble())
                std.NominalValue = Decimal.Round(number, 0)
                testStackClass.Dimensions.Add(std)
            Next
            Return testStackClass
        End Function
     
    End Class
    bon code......................

  6. #6
    Membre confirmé
    Homme Profil pro
    Technicien de bureau d etude
    Inscrit en
    Avril 2011
    Messages
    111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Technicien de bureau d etude
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2011
    Messages : 111
    Par défaut
    Bonjour Mabrouki,

    Merci encore pour ton aide, effectivement il faut tout reseter !

    Entre temps j'ai un peu avancé sur mon projet, j'ai remplacé le datagrid par un Control utilisateur que je multiplie pour visualiser ma liste et j'ai aussi étoffé le contenu de ma class.

    Quoi qu'il soit tes informations m'ont été trés utile et m'ont permis d'avancé ! Merci !

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

Discussions similaires

  1. [Débutant] DataBinding sur un objet personalisé
    Par Rainui dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 28/08/2013, 17h02
  2. Réponses: 2
    Dernier message: 29/09/2004, 09h07
  3. [Debutant VC++.net] Obtenir un pointeur sur objet
    Par SteelBox dans le forum MFC
    Réponses: 6
    Dernier message: 17/06/2004, 18h36
  4. [VB.NET] Instanciation objet (sur class perso.)
    Par DaxTaz dans le forum ASP.NET
    Réponses: 4
    Dernier message: 03/05/2004, 11h07
  5. ip fixeou nom de domaine sur ordi perso
    Par windob dans le forum Développement
    Réponses: 15
    Dernier message: 14/01/2004, 10h49

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