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 :

Conseil pour que ma classe devienne serializable


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut Conseil pour que ma classe devienne serializable
    Bonsoir à tous,
    Je suis désolé de solliciter à nouveau le forum mais je suis devant un problème insoluble (à mon niveau du moins).
    Vous avez peut-être suivi mon précédent post ?! Dans ma classe je crée dynamiquement des contrôles (PictureBox) et quand j'ai commencé à écrire ma classe ça m'a paru plus approprié d'inclure ces contrôles dans celle-ci.
    Probléme, j'avais prévu de serializer ma classe et ce n'est plus possible a cause des ces contrôles. J'ai ce message d'erreur :
    Le type 'System.Windows.Forms.PictureBox' dans l'assembly 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' n'est pas marqué comme sérialisable.
    J'ai cherché partout, et impossible de trouver une information qui me permettrais d'avancer.
    Je suis prêt à réécrire complètement ma classe si il faut (ça sera que la 3eme ou 4eme fois mais avant je voudrais être sûre qu'on ne peux pas sérialiser des contrôles. je pense peut-être à sortir ces contrôles de ma classe pour ne garder que leurs propriétés afin de travailler avec des variables simples mais ça va m’obliger a recharger leurs propriétés une à une au moment de la deserialization.
    Quelqu'un peut me dire comment on doit faire dans ce cas ?
    En vous remerciant d'avance beaucoup. (J'ai déjà pas mal sollicité le site).

  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 BasicZX8...
    Les controls winform herite de MarshallByRef qui n'est serializable...
    Pour serialization le contenu de chaque picturebox il faut definir :
    -un class auxiliaire PicBoxInfo qui store les props qu'on veut serializer (Pixels(),image.width,stride,name....)
    -un List(of PicBoxInfo)
    -serializer chaque element de ce List(of PicBoxInfo)
    -deserializer chaque element de ce List(of PicBoxInfo)

    voic un code simple qui serialize trois pictures et les deserializes:

    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
     
    Imports System.IO
    Imports System.Collections
    Imports System.Runtime.Serialization.Formatters.Binary
    Imports System.Runtime.Serialization
     
    Public Class Form1
        Private PicBoxList As New List(Of PicBoxInfo)
        Public Sub New()
     
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
     
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            Me.PictureBox1.Image = My.Resources.laptop
            Me.PictureBox2.Image = My.Resources.mouse
            Me.PictureBox3.Image = My.Resources.giraffe
     
        End Sub
        'Create a list of PictureBox info with every picture box on the form
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreateListPicInfo.Click
            For Each Control As Control In Me.Controls
                If TypeOf Control Is PictureBox Then
                    Dim ThisPictureBox As PictureBox = DirectCast(Control, PictureBox)
                    '//Get the image info
                    Dim BaseImage As New Bitmap(ThisPictureBox.Image.Width, PictureBox1.Image.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
                    BaseImage = CType(ThisPictureBox.Image, Bitmap)
                    Dim rect As New Rectangle(0, 0, BaseImage.Width, BaseImage.Height)
                    Dim bitmapData As System.Drawing.Imaging.BitmapData = BaseImage.LockBits(rect, _
                                  Drawing.Imaging.ImageLockMode.ReadWrite, _
                                  BaseImage.PixelFormat)
                    Dim Pointer As IntPtr = bitmapData.Scan0
                    Dim bytes As Integer = bitmapData.Stride * BaseImage.Height
                    Dim Pixels(bytes - 1) As Byte
                    System.Runtime.InteropServices.Marshal.Copy(Pointer, Pixels, 0, bytes)
                    BaseImage.UnlockBits(bitmapData)
                    '//Put these info in the list
                    Dim ThisPicBoxInfo As New PicBoxInfo
                    With ThisPicBoxInfo
                        'if needed, add other properties
                        .width = BaseImage.Width
                        .height = BaseImage.Height
                        .stride = bitmapData.Stride
                        .Pixels = Pixels
                        .Name = ThisPictureBox.Name
                        .Location = ThisPictureBox.Location
                    End With
                    PicBoxList.Add(ThisPicBoxInfo)
                End If
            Next
     
        End Sub
        'Serialize the list to a file
        Private pathApp As String = Directory.GetCurrentDirectory & "\GameImage.bin"
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSerializeListPicInfo.Click
            Dim BinFormatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
            Dim Stream As System.IO.Stream = File.Open(pathApp, FileMode.Create)
            BinFormatter.Serialize(Stream, PicBoxList)
            Stream.Close()
            PicBoxList.Clear()
     
        End Sub
        'read back the file and deserialize
     
        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeserializeListPicInfo.Click
            Dim BinFormatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
            Dim Stream As System.IO.Stream = File.Open(pathApp, FileMode.Open)
            PicBoxList = DirectCast(BinFormatter.Deserialize(Stream), List(Of PicBoxInfo))
            Stream.Close()
     
        End Sub
        'Create a picturebox from one of the picturebox info in the list
        Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
            'Create a picture box
            Dim ThisPictureBox As New PictureBox
            ThisPictureBox.Width = PicBoxList.Item(0).width
            ThisPictureBox.Height = PicBoxList.Item(0).height
            ThisPictureBox.Location = New Point(300, 200)
            'Create the image from the info
            Dim BaseImage As New Bitmap(PicBoxList.Item(0).width, PicBoxList.Item(0).height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
            Dim rect As New Rectangle(0, 0, BaseImage.Width, BaseImage.Height)
            Dim bitmapData As System.Drawing.Imaging.BitmapData = BaseImage.LockBits(rect, _
                          Drawing.Imaging.ImageLockMode.ReadWrite, _
                          BaseImage.PixelFormat)
            Dim Pointer As IntPtr = bitmapData.Scan0
            Dim bytes As Integer = PicBoxList.Item(0).stride * BaseImage.Height
            Dim Pixels() As Byte = PicBoxList.Item(0).Pixels
            System.Runtime.InteropServices.Marshal.Copy(Pixels, 0, Pointer, bytes)
            BaseImage.UnlockBits(bitmapData)
            ' put the image in a picture box
            ThisPictureBox.Image = BaseImage
            'Add the picture box to the form
            Me.Controls.Add(ThisPictureBox)
     
        End Sub
     
    End Class
    <Serializable()> _
    Class PicBoxInfo
        Public Pixels() As Byte
        Public width As Integer
        Public stride As Integer
        Public height As Integer
        Public Name As String
        Public Location As Point
    End Class
    bon code......................

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut
    Merci beaucoup Mabrouki,
    Ca fait plaisir d'avoir des réponses, je vais tester cette solution et j'espère enfin pouvoir avancer.
    Mon Appli est au point mort depuis 1 semaine à cause de ça.

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut
    Bonsoir, le code de Mabrouki fonctionne à merveille mais en fait ça ne réponds qu'en partie à mon problème.
    En effet je peux serializer les propriétés simples (qui correspondent aux Propriétés des PictureBox) mais pas les pictureBox eux mêmes.
    Est ce que une classe peut être informée qu'elle vient d'être deserializé (par son constructeur New peut-être, je ne sais pas ?!), ça me permettrait de lancer une procédure à ce moment là pour restaurer les instances des PictureBox ?. Cette procédure ferait partie de ma classe, pour l'instant j'ai décider de tout gérer depuis ma classe.

  5. #5
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut
    J'ai trouvé :

    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
        <Serializable()>
        Public Class clsVideoEditCuts
            Implements ISerializable, IDeserializationCallback
            Private _SortedListVideoEditCut As SortedList
            Dim _Container As PictureBox
            Dim _NbFrames As Integer
            Dim _ListBox As ListBox
            Dim _SCGXtl As Integer
            Dim _SCGYtl As Integer
            Private _Compteur As Integer
    #Region "ISerializable Members and déserialisable constructor"
            Protected Sub New(info As SerializationInfo, context As StreamingContext)
                ' Propriétés a deserializer
                '...
                '_NbFrames = DirectCast(info.GetValue("NbFrames", GetType(Integer)), Integer)
                _NbFrames = info.GetInt32("NbFrames")
                _SCGXtl = info.GetInt32("SCGXtl")
                _SCGYtl = info.GetInt32("SCGYtl")
                _Compteur = info.GetInt32("Compteur")
            End Sub
     
            Public Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext) Implements System.Runtime.Serialization.ISerializable.GetObjectData
                ' propriétés a serializer
                info.AddValue("NbFrames", _NbFrames)
                info.AddValue("Info", _SCGXtl)
                info.AddValue("Majeur", _SCGYtl)
                info.AddValue("Majeur", _Compteur)
            End Sub
            Public Sub OnDeserialization(ByVal sender As Object) Implements System.Runtime.Serialization.IDeserializationCallback.OnDeserialization
                Dim ThisPictureBox As New PictureBox
                ' ici on Restaure les PictureBox
                ' ......
            End Sub
    #End Region
     
            Public Sub New(ByVal NbFrames As Integer)
     
            End Sub

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

Discussions similaires

  1. Conseil pour créer une classe de sauvegarde de configuration
    Par hdgetnet dans le forum Général Python
    Réponses: 5
    Dernier message: 28/11/2010, 08h34
  2. Débutant : Conseil pour diagramme de classe
    Par Looney dans le forum Débuter
    Réponses: 0
    Dernier message: 11/10/2009, 23h28
  3. Comment faire pour que mon image devienne un lien
    Par pierrot10 dans le forum Général JavaScript
    Réponses: 38
    Dernier message: 25/06/2007, 20h49
  4. Réponses: 6
    Dernier message: 25/08/2006, 15h16
  5. Conseils pour l'écriture d'une Classe
    Par delphi5user dans le forum Delphi
    Réponses: 10
    Dernier message: 12/07/2006, 22h51

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