2009-08-04 13 views
2

J'essaie de sérialiser une classe qui dérive de BindingList (étage), où étage est une classe simple qui contient seulement une propriété étage. hauteurChamps publics/propriétés d'une classe dérivée de BindingList <T> coutume sérialisent

Voici une version simplifiée de ma classe

[Serializable] 
[XmlRoot(ElementName = "CustomBindingList")] 
public class CustomBindingList:BindingList<Floor> 
{ 
    [XmlAttribute("publicField")] 
    public string publicField; 
    private string privateField; 

    [XmlAttribute("PublicProperty")] 
    public string PublicProperty 
    { 
     get { return privateField; } 
     set { privateField = value; } 
    } 
} 

Je sérialiser une instance de CustomBindingList en utilisant le code suivant.

XmlSerializer ser = new XmlSerializer(typeof(CustomBindingList)); 
StringWriter sw = new StringWriter(); 

CustomBindingList cLIst = new CustomBindingList(); 

Floor fl; 

fl = new Floor(); 
fl.Height = 10; 
cLIst.Add(fl); 

fl = new Floor(); 
fl.Height = 10;  
cLIst.Add(fl); 

fl = new Floor(); 
fl.Height = 10; 
cLIst.Add(fl); 

ser.Serialize(sw, cLIst); 

string testString = sw.ToString(); 

Cependant testString termine au-dessus se défini sur le code XML suivant:

<CustomBindingList xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"> 
    <Floor Height="10" /> 
    <Floor Height="10" /> 
    <Floor Height="10" /> 
</CustomBindingList>" 

Comment puis-je obtenir "publicField" ou « publicProperty sérialiser ainsi

+0

provenant de la classe presque toute collection de système est une * très mauvaise idée *. implémenter une interface ne s'étend pas. – ShuggyCoUk

+1

Je ne voulais pas dériver de IBindingList parce que ce n'est pas générique, et je n'aime pas les collections non génériques où je dois transtyper sur mon vrai type d'objet chaque fois que je veux faire quelque chose. –

+2

L'attribut '[Serializable]' est ignoré par XML Serialization. Vous devriez l'enlever. –

Répondre

2

La sérialisation XML gère les collections d'une manière spécifique et ne sérialise jamais les champs ou les propriétés de la collection, mais uniquement les éléments.

Vous pouvez soit:

  • mettre en œuvre IXmlSerializable pour générer et analyser le XML vous-même (mais il est beaucoup de travail)
  • envelopper votre BindingList dans une autre classe, dans laquelle vous déclarez vos champs personnalisés (comme suggérée par speps)
+0

J'ai fini par implémenter IXMLSerializable. Le problème avec l'encapsulation/encapsulation BindingList est que le point d'utiliser BindingList est qu'il a des événements qui lui permettent d'être attachés aux éléments de l'interface graphique, comme un DataGrid, très facile. Donc, si j'encapsulais la BindingList, la classe résultante n'aurait aucun de ces événements. –

+0

Vous pouvez toujours lier le DataGrid à la propriété qui expose BindingList ... –

1

C'est problème connu avec la sérialisation XML et l'héritage des collections

Vous pouvez lire plus d'informations à ce sujet ici: http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/0d94c4f8-767a-4d0f-8c95-f4797cd0ab8e

Vous pouvez essayer quelque chose comme ceci:

[Serializable] 
[XmlRoot] 
public class CustomBindingList 
{ 
    [XmlAttribute] 
    public string publicField; 
    private string privateField; 

    [XmlAttribute] 
    public string PublicProperty 
    { 
     get { return privateField; } 
     set { privateField = value; } 
    } 

    [XmlElement] 
    public BindingList<Floor> Floors = new BindingList<Floor>(); 
} 

Cela signifie que vous pouvez ajouter des planchers en utilisant Floors.Add et vous obtiendrez le résultat que vous voulez, je l'espère, cependant, je n'ai pas essayé . Gardez à l'esprit que jouer avec les attributs est la clé de la sérialisation XML.

3

La réponse ici est que .NET attend généralement quelque chose à être une collection XOR avoir prope rties. Cela se manifeste dans quelques endroits:

  • sérialisation xml; les propriétés des collections ne sont pas sérialisées
  • liaison de données; vous ne pouvez pas des données se lient à des propriétés sur les collections, car il vous faut implicitement au premier élément au lieu

Dans le cas de sérialisation XML, il est logique si l'on considère qu'il pourrait juste être un SomeType[] au client ... où iraient les données supplémentaires?

La solution commune consiste à encapsuler une collection - c'est-à-dire.plutôt que

public class MyType : List<MyItemType> // or BindingList<...> 
{ 
    public string Name {get;set;} 
} 

public class MyType 
{ 
    public string Name {get;set;} 
    public List<MyItemType> Items {get;set;} // or BindingList<...> 
} 

Normalement, je ne voudrais pas avoir un set sur une propriété de collection, mais exige XmlSerializer ... il

Questions connexes