繁体   English   中英

C#序列化WinForm

[英]C# Serialize WinForm

我正在尝试序列化一个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 <>属性中,这没有什么区别。 其次,我尝试确保构造函数为空且没有参数。

序列化整个Form是一个坏主意,因为它不打算序列化:

  • 它具有很多不应序列化的属性(例如,显示相关属性)
  • 即使工作正常,您也会有很多与应用程序状态无关的数据

正确的解决方案是将所有状态信息保留在您的自定义对象中,并使用WinForm的数据绑定功能绑定到那些对象。 如果这意味着对您的应用程序进行了很大的更改,请尝试仅序列化与构造状态有关的数据。

您如何知道哪些数据与应用程序状态相关?

在构造和显示表单之前,我希望您正在从数据库,文件等中加载数据。所有这些信息都应包含在明确定义的带有[Serializable]属性的类型的对象中。 这样,很容易随意对其进行序列化和反序列化。

同样,重要的是要考虑到版本兼容的序列化,或者在更改表单/状态信息(例如,添加字段)并且使用较旧的XML来恢复状态时发生的情况。

每个表单都有其自己的机制来存储和检索(序列化和反序列化)数据,并且它会自动执行此操作。 但是,必须满足以下条件才能自动使用此功能。

-  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对象,但是...

  • 只有属性X将被序列化,因为它符合自动序列化的必要状态。
  • 由于DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),无法对属性Y进行序列化
  • 属性Z无法自动序列化,因为它没有公共设置访问者。

为了序列化Y和Z,需要自定义序列化代码。 在大多数情况下,不需要自定义序列化,自定义序列化可以通过多种方式完成,但这是一个很大的话题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM