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

C# Discussion :

pb serialization List<Color>


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Inscrit en
    Juin 2004
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 2
    Par défaut pb serialization List<Color>
    Bonjour,

    Je n'arrive pas à déserialiser une liste de couleurs (la sérialisation semble fonctionner). Voici la classe que je souhaite sérialiser / désérialiser :

    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 Param
      {
        public string name;
        public int age;
        public List<string> friends;
        [XmlIgnoreAttribute()]    
        public List<Color> colors;
        public List<string> htmlColors
        {
          get
          {
            List<String> res = new List<string>();
            foreach (Color color in colors)
            {
              res.Add(ColorTranslator.ToHtml(color));
            }
            return res;
          }
     
          set
          {
            colors = new List<Color>();
            foreach (String color in value)
            {
              colors.Add(ColorTranslator.FromHtml(color));
            }
          }
        }
     
        public Param()
        {
        }
      }
    Un exemple de sérialisation me donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <?xml version="1.0" encoding="utf-16"?><Param xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><name>Bob</name><age>15</age><friends><string>Gérard</string><string>Emile</string><string>Jean</string></friends><htmlColors><string>#FF0000</string><string>#FFFF00</string></htmlColors></Param>
    Cela me convient mais lors de la désérialisation de cette chaine, je ne comprends pas pourquoi, c'est le getter de la propriété htmlColors qui est appelé au lieu du setter...

    Je sais que je pourrais implémenter IXmlSerializable et définir manuellement ReadXml() mais je demande à tout hasard si quelqu'un aurait une solution pour éviter cela car j'ai de nombreuses classes de ce type à sérializer.

    Merci !

  2. #2
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Salut

    Color n'est pas serializable directement

    J'utilise une petite classe wrapper pour exposer les propriétés a serialiser

    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
    using System.Drawing;
     
    namespace Mapscope.BcTools
    {
      public class ColorSerializable
      {
     
        public int A;
        public int R;
        public int G;
        public int B;
     
        public static ColorSerializable FromColor(Color _color)
        {
          ColorSerializable sCol = new ColorSerializable();
          sCol.A = _color.A;
          sCol.R = _color.R;
          sCol.G = _color.G;
          sCol.B = _color.B;
          return sCol;
        }
     
        public Color ToColor()
        {
          return ColorSerializable.ToColor(this);
        }
     
        public static Color ToColor(ColorSerializable sCol)
        {
          Color _color = Color.FromArgb(sCol.A, sCol.R, sCol.G,sCol.B);
          return _color;
        }
      }
    }

  3. #3
    Rédacteur/Modérateur


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

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Floyanami Voir le message
    Cela me convient mais lors de la désérialisation de cette chaine, je ne comprends pas pourquoi, c'est le getter de la propriété htmlColors qui est appelé au lieu du setter...
    J'avais expliqué ce comportement dans mon tuto :
    http://tlevesque.developpez.com/dotn...zation/#LI-B-2

    En gros, le XmlSerializer récupère la collection par le get pour ensuite y ajouter les éléments, plutôt que de créer une collection et de l'affecter avec le set. En fait, il initialise la collection avec le set seulement si le get a renvoyé null... mais il l'initialise avec une collection vide, et ajoute les éléments seulement après.

    Dans ton cas, le get de htmlColors renvoie une collection, et c'est à cette collection que les couleurs désérialisées sont ajoutées. Sauf que toi, tu n'as plus la trace de cette collection, et tu ne peux donc pas l'utiliser pour initialiser colors...

    Je ne vois pas de solution vraiment simple pour ton problème... Mais en comprenant bien le mécanisme de la désérialisation, il y a toujours moyen de bidouiller

    Je te propose la solution suivante (cette solution suppose que tu n'utilises la propriété HtmlColors que pour la sérialisation/désérialisation, si ce n'est pas le cas, crée une nouvelle propriété juste pour ç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
    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
            private List<Color> _colors = null;
     
            [XmlIgnore]
            public List<Color> Colors
            {
                get
                {
                    if (_colors == null)
                    {
                        _colors = new List<Color>();
                    }
     
                    if (_deserializedHtmlColors != null)
                    {
                        foreach (string hColor in _deserializedHtmlColors)
                        {
                            _colors.Add(ColorTranslator.FromHtml(hColor));
                        }
                        _deserializedHtmlColors = null;
                    }
     
                    return _colors;
                }
            }
     
            private List<string> _deserializedHtmlColors = null;
     
            [XmlArray("Colors")]
            [XmlArrayItem("Color")]
            public List<string> HtmlColors
            {
                get
                {
                    if (_deserializedHtmlColors != null)
                    {
                        return _deserializedHtmlColors;
                    }
                    else if (_colors != null)
                    {
                        List<string> htmlColors = new List<string>();
                        foreach (Color color in this._colors)
                        {
                            htmlColors.Add(ColorTranslator.ToHtml(color));
                        }
                        return htmlColors;
                    }
                    else return null;
                }
                set
                {
                    _deserializedHtmlColors = value;
                }
            }
    En gros, lors de la désérialisation :
    - l'objet vient d'être créé, donc _colors n'est pas encore initialisé, donc le get de HtmlColors renvoie null.
    - donc le XmlSerializer affecte une nouvelle liste (vide) à HtmlColors, dont on garde une référence (_deserializedHtmlColors)
    - le XmlSerializer ajoute à cette liste les couleurs désérialisées
    - lors du premier accès à la propriété Colors, on voit qu'il y a quelque chose dans _deserializedHtmlColors, on sait donc que l'objet a été créé par la désérialisation. On initialise donc _colors avec le contenu de _deserializedHtmlColors, puis on met _deserializedHtmlColors à null (car on ne veut faire cette initialisation qu'une seule fois)

    Comme je le disais, c'est de la grosse bidouille, et un peu galère à mettre en œuvre si tu dois le faire dans beaucoup de classes... mais c'est toujours moins long qu'implémenter IXmlSerializable

  4. #4
    Candidat au Club
    Inscrit en
    Juin 2004
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 2
    Par défaut
    Pas de problème c'est beaucoup mieux que d'implémenter IXmlSerializable !
    Merci infiniment pour l'explication et la solution

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

Discussions similaires

  1. Liste déroulante color
    Par benhsaien dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 13/09/2011, 13h36
  2. Serialization d'une List<FileInfo> => Error reflecting types
    Par Radec dans le forum Windows Forms
    Réponses: 2
    Dernier message: 17/07/2008, 10h10
  3. VBA Colorer la plus grande valeur d'une liste
    Par Toad08 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 10/03/2008, 17h23
  4. [VBA]Colorer ligne d'une liste
    Par docky dans le forum VBA Access
    Réponses: 1
    Dernier message: 16/04/2007, 14h45
  5. colorer une liste déroulante
    Par 18Marie dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 18/08/2006, 22h36

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