2016-11-14 4 views
3

я создал классПолучение Serializable Ошибка Даже после установки [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

В комментариях и ответах Кубы сказано, что PictureBox и Label не являются сериализуемыми, и это является причиной ошибки. Недостаточно украсить класс атрибутом 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[])); 
     } 
    } 
} 

Тогда для сериализации и десериализации, вы можете добавить Save и Load метод класса.

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; 
Смежные вопросы