2016-11-14 61 views
3

之前之后我创建了一个类现在获取序列化的错误,即使插入[Serializable接口]

[Serializable] 
public class clsCategories 
{ 
    public static List<infoCategories> listCategories = new List<infoCategories>(); 
    public void serialize() 
    { 
     BinaryFormatter bf = new BinaryFormatter(); 
     FileStream fs = new FileStream("categories.dat", FileMode.Create); 
     bf.Serialize(fs, listCategories); 
     fs.Close(); 
    } 

    [Serializable] 
    public class infoCategories 
    { 
     public PictureBox img { get; set; } 
     public Label lbl { get; set; } 
    } 
} 

调用此方法时...

private void btnDone_Click(object sender, EventArgs e) 
{ 
    objCategories.serialize(); 
    this.Hide(); 
} 

我得到这个错误:

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll

Additional information: Type 'System.Windows.Forms.PictureBox' in Assembly 'System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

我错在哪里?

+0

所有成员都必须是可序列化。 'PictureBox'和'Label'不是。 –

+0

@IvanStoev但我写了 [Serializable] 高于他们的类。我仍然错过了什么?如果是的话,告诉我 – ShoaibSivany

+0

你可以序列化一个位图,或者你可以创建一个类SerilizablePictureBox。只需添加属性并不总是足够的。 – TaW

回答

4

当序列化类型为infoCategories的对象列表时 - 将对这些对象的所有属性进行序列化。 img属性也是如此,它属于PictureBox类型。由于PictureBox本身不是可序列化的,因此会出现错误。

顺便说一句,Label lbl也会发生。没有窗口控制可以这样序列化AFAIK。

你有什么选择?

首先:用[NonSerialized]标记班级中所有不可序列化的字段。这使得序列化程序在读取和写入期间跳过属性。但是,由于这基本上会导致一个空课 - 这可能不是一个好的选择。

另一种选择是序列化保存和使用它们恢复对象所需的很平淡数据。因此,不是序列化Label,而是序列化string,这恰好是该标签的文本。反序列化后,您可以重新创建字符串列表中的标签列表。这同样适用于图片框中包含的图像(可以将base64编码为字符串)。

最后一个选项是序列化代理(Is it possible to do .NET binary serialization of an object when you don't have the source code of the class?),但这在这里可能会过度。

2

这是在评论和库巴的回答中说,PictureBoxLabel不可序列化,这就是错误的原因。仅用Serializable属性装饰一个类是不够的,它的所有属性也应该是Serializable

相反,您可以创建一个包含字符串和图像的类并尝试序列化它。但不幸的是Image也不可序列化。

注:我没有使用Bitmap,因为PicturebBox的图像可能是gif或其他东西。

如何序列化包含图像和字符串的类?

对于图像,您应该将其序列化为byte[]。所以,你可以创建一个这样的类:

using System; 
using System.Drawing; 
using System.IO; 
using System.Runtime.Serialization.Formatters.Binary; 

[Serializable] 
public partial class MyData 
{ 
    public string Label { get; set; } 
    byte[] bytes; 
    [NonSerialized] 
    Image image; 
    public Image Image 
    { 
     get 
     { 
      if (image == null && bytes != null) 
       image = (Image)((new ImageConverter()).ConvertFrom(bytes)); 
      return image; 
     } 
     set 
     { 
      image = value; 
      bytes = (byte[])new ImageConverter().ConvertTo(value, typeof(byte[])); 
     } 
    } 
} 

然后序列化和反序列化,你可以添加一个SaveLoad方法的类。

public partial class MyData 
{ 
    public void Save(string file) 
    { 
     using (Stream stream = File.Open(file, FileMode.Create)) 
     { 
      BinaryFormatter bin = new BinaryFormatter(); 
      bin.Serialize(stream, this); 
     } 
    } 
    public static MyData Load(string file) 
    { 
     using (Stream stream = File.Open(file, FileMode.Open)) 
     { 
      BinaryFormatter bin = new BinaryFormatter(); 
      return (MyData)bin.Deserialize(stream); 
     } 
    } 
} 

而且这里有一个例子用法:

var m1 = new MyData() { Label = label1.Text, Image = pictureBox1.Image }; 
m1.Save(@"d:\m1.dat"); 
var m2 = MyData.Load(@"d:\m1.dat"); 
label2.Text = m2.Label; 
pictureBox2.Image = m2.Image;