自己實作物件序列化
因內建序列化與所需有差異,所以就自行打造:
序列化後的結果:
<?xml version="1.0" encoding="utf-16"?>
<Object TabStop="False" Text="groupBox1" Dock="Left" Location="4, 4" Margin="4, 4, 4, 4" Name="groupBox1" Size="667, 438" TabIndex="3" Padding="4, 4, 4, 4" type="System.Windows.Forms.GroupBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll">
<Object TabStop="False" Text="groupBox1" Dock="Fill" Location="4, 81" Margin="4, 4, 4, 4" Name="groupBox3" Size="659, 353" TabIndex="3" Padding="4, 4, 4, 4" type="System.Windows.Forms.GroupBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll">
<Object RightSideBlank="5" Culture="Chinese (Taiwan)" Dock="Bottom" Location="4, 174" Margin="4, 4, 4, 4" Name="weekCalendar1" Size="651, 175" TabIndex="3" Padding="8, 8, 8, 8" type="Workstation.WeekCalendar" assembly="D:\Projects\PlugInSample\MainApp\Workstation.exe" />
<Object Multiline="True" Location="371, 19" Margin="4, 4, 4, 4" Name="textBox5" Size="148, 104" TabIndex="10" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object Location="112, 106" Margin="4, 4, 4, 4" Name="textBox4" Size="148, 26" TabIndex="9" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object Location="112, 77" Margin="4, 4, 4, 4" Name="textBox3" Size="148, 26" TabIndex="8" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object Location="112, 48" Margin="4, 4, 4, 4" Name="textBox2" Size="148, 26" TabIndex="7" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object Location="112, 19" Margin="4, 4, 4, 4" Name="textBox1" Size="148, 26" TabIndex="6" type="System.Windows.Forms.TextBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object AutoSize="True" Text="label10" Location="45, 22" Margin="4, 0, 4, 0" Name="label10" Size="59, 18" TabIndex="5" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object AutoSize="True" Text="label9" Location="304, 26" Margin="4, 0, 4, 0" Name="label9" Size="50, 18" TabIndex="4" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object AutoSize="True" Text="label8" Location="45, 112" Margin="4, 0, 4, 0" Name="label8" Size="50, 18" TabIndex="3" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object AutoSize="True" Text="label7" Location="45, 82" Margin="4, 0, 4, 0" Name="label7" Size="50, 18" TabIndex="2" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object AutoSize="True" Text="label6" Location="45, 52" Margin="4, 0, 4, 0" Name="label6" Size="50, 18" TabIndex="1" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
</Object>
<Object TabStop="False" Text="groupBox1" Dock="Top" Location="4, 23" Margin="4, 4, 4, 4" Name="groupBox2" Size="659, 58" TabIndex="3" Padding="4, 4, 4, 4" type="System.Windows.Forms.GroupBox" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll">
<Object AutoSize="True" Text="label5" Location="281, 28" Margin="4, 0, 4, 0" Name="label5" Size="50, 18" TabIndex="2" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object AutoSize="True" Text="label4" Location="183, 28" Margin="4, 0, 4, 0" Name="label4" Size="50, 18" TabIndex="1" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
<Object AutoSize="True" Text="label3" Location="93, 28" Margin="4, 0, 4, 0" Name="label3" Size="50, 18" TabIndex="0" type="System.Windows.Forms.Label" assembly="C:\windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" />
</Object>
</Object>
序列化及反序列化程式
public static void ToXml(this object obj, XmlWriter xml)
{
var props = TypeDescriptor.GetProperties(obj);
xml.WriteStartElement("Object");
foreach (PropertyDescriptor p in props)
{
if (p.SerializationVisibility != DesignerSerializationVisibility.Visible) continue;
if (!p.ShouldSerializeValue(obj)) continue;
var raw = p.GetValue(obj);
if (raw == null) continue;
if (p.Converter == null) continue;
var value = p.Converter.ConvertToInvariantString(raw);
xml.WriteAttributeString(p.Name, value);
}
var type = TypeDescriptor.GetReflectionType(obj);
xml.WriteAttributeString("type", type.FullName);
xml.WriteAttributeString("assembly", type.Assembly.Location);
if (props["Controls"] != null)
{
var controls = props["Controls"].GetValue(obj) as IList;
if (controls != null && controls.Count > 0)
foreach (var c in controls)
ToXml(c, xml);
}
xml.WriteEndElement();
}
public static object CreateObject(this XmlNode node)
{
if (node.Name != "Object") return null;
if (node.Attributes == null) return null;
var attr = new Dictionary<string, string>();
foreach (XmlAttribute a in node.Attributes)
attr[a.Name] = a.Value;
if (!attr.ContainsKey("assembly") || !attr.ContainsKey("type")) return null;
try
{
var asm = Assembly.LoadFrom(attr["assembly"]);
var obj = asm.CreateInstance(attr["type"]);
if (obj == null) return null;
var props = TypeDescriptor.GetProperties(obj);
foreach (var a in attr)
{
if (props[a.Key] == null) continue;
var converter = props[a.Key].Converter;
if (converter == null) continue;
var value = converter.ConvertFromInvariantString(a.Value);
if (value != null)
props[a.Key].SetValue(obj, value);
}
var ctrl = obj as Control;
if (ctrl == null) return obj;
foreach (XmlNode childNode in node.ChildNodes)
{
var child = childNode.CreateObject();
if (child == null) continue;
var childCtrl = child as Control;
if (childCtrl != null)
ctrl.Controls.Add(childCtrl);
}
return obj;
}
catch (Exception)
{
return null;
}
}