2016-11-14 57 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;