簡體   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