存取類執行個體的參數最佳的方法當然是串行化技術,串行化支援兩種方式:二進制方式,可以高保真的儲存類示例,另一種是XML方式,它僅儲存公共資料。很可惜.net 2.0的精簡架構集僅支援XML方式。
我這裡做了一個示例,實作的功能是在PC機上可以畫很多圖形,用串行化方式儲存相關資訊,把相關資訊下載下傳到wince中,由wince中的c#程式讀取串行化資訊,并把相關類的執行個體資訊還原出來。
這裡面有個關鍵,圖形類有可能有多個(示例為2個),而目前我查相關資料,都是一個類的串行化存取,并且如果你存兩個以上的類,用XML是可以存取成功的,但是讀取的時候它會告訴你失敗。是以這裡引入了ArrayList類的相關概念。
也就是說,我定義了一個類,類中的一個屬性為ArrayList類的執行個體,這樣用ArrayList執行個體我可以存儲很多的類資訊。
同樣,不作任何處理用一般方法存儲是成功的,但是在讀取時,你發現ArrayList執行個體中的資料,都是object類型,原類型資訊丢失!
這怎麼辦?繼續查資料,發現有兩種方法可以解決這個問題。
1、 [XmlElement(Type = typeof(YFRect)), XmlElement(Type = typeof(YFCircle))]
public ArrayList gData = new ArrayList(); //圖中繼資料
在類中添加XmlElement聲明,把ArrayList 類執行個體中有可能添加的類都标示出。
2、在存取資料時,用代碼告訴XML串行化相關類的類型
Type[] gt = new Type[2]; //圖元類型數組
gt[0] = typeof(YFRect);
gt[1] = typeof(YFCircle);
Stream sf = new FileStream(strXmlFile, FileMode.Open, FileAccess.Read, FileShare.None);
XmlSerializer xmls = new XmlSerializer(typeof(YFGraphicsData), gt);
XmlData = (YFGraphicsData)xmls.Deserialize(sf);
sf.Close();
這是運作後的結果:
相關代碼:clsGraphics.cs (圖元類)
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Drawing;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
namespace YFXMLSaveLoad
{
//圖中繼資料類
public class YFGraphicsData
{
//[XmlElement(Type = typeof(YFRect)), XmlElement(Type = typeof(YFCircle))]
//當代碼傳入類型數組時,則不需要上面的聲明
public string strName = "測試";
public string strVer = "V1.0.0";
public ArrayList gData = new ArrayList(); //圖中繼資料
}
//串行化操作類
public class YFXMLSerialize
//串行化
public void XMLSerializer(YFGraphicsData XmlData,string strXmlFile)
{
Type[] gt = new Type[2]; //圖元類型數組
Stream sf = new FileStream(strXmlFile, FileMode.Create, FileAccess.Write, FileShare.None);
xmls.Serialize(sf, XmlData);
}
//反串行化
public void XMLDeserialize(out YFGraphicsData XmlData, string strXmlFile)
Type[] gt = new Type[2]; //圖元類型數組
}
//------------------------------------------------
public class YFGraphicsBase
{
public int width = 1;
//Color類不支援XML串行化
public int color = 0;
public virtual void Draw(Graphics e) { }
public class YFRect : YFGraphicsBase
public Rectangle xy;
public override void Draw(Graphics e)
e.DrawRectangle(new Pen(Color.FromArgb(color), width), xy);
public class YFCircle : YFGraphicsBase
public Rectangle xy;
e.DrawEllipse(new Pen(Color.FromArgb(color), width), xy);
}
Form1.cs 窗體代碼
using System.ComponentModel;
using System.Data;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.InteropServices;
{
public partial class Form1 : Form
YFGraphicsData XmlData = new YFGraphicsData(); //圖中繼資料
YFXMLSerialize XmlWork = new YFXMLSerialize(); //XML串行化方法
public Form1()
InitializeComponent();
panel1.Refresh();
//自繪
private void button4_Click(object sender, EventArgs e)
YFRect yfr001=new YFRect();
YFRect yfr002 = new YFRect();
YFCircle yfc001 = new YFCircle();
yfr001.color = Color.Blue.ToArgb();
yfr001.xy.X = 10;
yfr001.xy.Y = 10;
yfr001.xy.Width = 50;
yfr001.xy.Height = 50;
yfr002.color = Color.FromArgb(0, 0, 0).ToArgb();
yfr002.width = 2;
yfr002.xy.X = 30;
yfr002.xy.Y = 50;
yfr002.xy.Width = 100;
yfr002.xy.Height = 80;
yfc001.color = Color.Red.ToArgb();
yfc001.xy.X = 20;
yfc001.xy.Y = 20;
yfc001.xy.Width = 80;
yfc001.xy.Height = 90;
XmlData.gData.Clear();
XmlData.gData.Add(yfr001);
XmlData.gData.Add(yfc001);
XmlData.gData.Add(yfr002);
panel1.Refresh();
}
//繪圖
private void panel1_Paint(object sender, PaintEventArgs e)
e.Graphics.Clear(Color.PapayaWhip);
foreach (YFGraphicsBase dw in XmlData.gData)
{
dw.Draw(e.Graphics);
}
textBox1.Text = XmlData.gData.Count.ToString();
//清圖元
private void button3_Click(object sender, EventArgs e)
//儲存圖元
private void button2_Click(object sender, EventArgs e)
//圖元串行化
XmlWork.XMLSerializer(XmlData,"TuData.xml");
//------
MessageBox.Show("OK");
//調入圖元
private void button1_Click(object sender, EventArgs e)
//圖元反串行化
XmlWork.XMLDeserialize(out XmlData, "TuData.xml");
//------
}
//-----------------------------------