我正在尝试序列化winform,其最终目标是能够在表单的各种控件中重新创建值。我的表单包含典型的控件,按钮/单选按钮/复选框/文本框/列表框/选项卡控件。
我收到此错误:
An exception of type 'System.InvalidOperationException' occurred
in System.Xml.dll but was not handled in user code
Additional information: There was an error reflecting type
'Receptionist_Program.Objects.Client.Client_NCQ'.
我为要保存的每个值设置属性:
public bool CbMedTreat
{
get { return cbMedTreat.Checked; }
set { cbMedTreat.Checked = value; }
}
public List<Client_AddDoctor> TxtDocExplain // Client_AddDoctor is another form
{
get { return listDoctors; }
set { listDoctors = value; }
}
// etc, variety of string and bool properties
在课程的顶部,我有装饰:
[Serializable]
public partial class Client_NCQ : Form
最后,这是我的代码进行序列化:
Client_NCQ badname = new Client_NCQ();
badname.Initialize();
badname.ShowDialog();
string result = "";
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Client_NCQ));
// Error occurs here on above line: new XmlSerializer(typeof(Client_NCQ))
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, badname);
result = textWriter.ToString();
}
到目前为止,我尝试了两种不同的东西,首先,我将装饰[XmlIgnore]添加到List&lt;&gt;财产,这没有区别。其次,我尝试确保构造函数为空且没有参数。
答案 0 :(得分:3)
序列化整个Form
是一个坏主意,因为它不是要序列化的:
正确的解决方案是将所有状态信息保存在自定义对象中,并使用WinForm的databinding功能绑定到这些对象。如果这意味着您的应用程序发生了很大的变化,请尝试仅序列化与构建状态相关的数据。
您如何知道哪些数据与应用程序状态相关?
在构建和显示表单之前,我希望您从数据库,文件等加载数据。所有这些信息都应包含在标有[Serializable]
属性的明确定义的对象中。这样,很容易随意序列化和反序列化。
此外,重要的是要考虑version tolerant serialization或更改表单/状态信息时发生的情况(例如添加字段),并使用较旧的XML来恢复状态。
答案 1 :(得分:0)
每个表单都有自己的机制来存储和检索(序列化和反序列化)数据,它会自动执行此操作。但是,要满足以下条件才能自动使用此功能。
- All properties which are desired to be serialized must have public get and set accesor.
- If a certain property represents custom object such as user defined class or struct, the object must be adorned with [Serializable] attribute.
- Property which is desired to be serialized must not have [DesignerSerializationVisibility] attribute set to Hidden. By default it is Visible so not specifying this attribute at all is sufficiently serves the purpose.
考虑这个例子:
namespace MnM.Drawing
{
[Serializable, TypeConverter(typeof(ExpandableObjectConverter))]
public class Coordinates
{
public int X { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int Y { get; set; }
public int Z { get; protected set; }
}
public class MyForm : Form
{
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public Coordinates MyCoordinates { get; set; }
}
}
现在,MyForm将自动序列化MyCoordinates对象,但是......
为了序列化Y和Z,需要自定义序列化代码。在大多数情况下,不需要自定义序列化,自定义序列化可以通过多种方式完成,但它是一个广泛的主题。