簡體   English   中英

在C#中序列化和反序列化XML以便重用XML文件,模型類和UserControl的最佳方法

[英]Best way to serialize and deserialize XML in C# so as to reuse the XML file, model class, and UserControl

我有一個XML文件,其中包含最終將在兩個UserControl中顯示的數據。 大多數數據是通用的,而某些是特定於所涉及的UserControl的。 我想成為一個好公民,並盡可能地重用代碼。 要給出一個具體示例(大大簡化),請考慮以下XML:

<?xml version="1.0"?>
<Model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<Widgets>
<Widget>
  <Name>Fork</Name>
  <VisibleAtHome>true</VisibleAtHome>
  <VisibleAtRestaurant>true</VisibleAtRestaurant>
</Widget>
<Widget>
  <Name>ProfessionalMixer</Name>
  <VisibleAtHome>false</VisibleAtHome>
  <VisibleAtRestaurant>true</VisibleAtRestaurant>
</Widget>
</Widgets>
</Model>

最終,我想在兩個UserControl上顯示此信息,一個用於家庭廚房,一個用於餐廳。 在這兩個控件上,我只想顯示

名稱:可見:

顯然,在“家用廚房”控件上,我想顯示“ VisibleAtHome”,在餐廳上顯示“ VisibleAtRestaurant”。 可能,我做事的方式是最好的。 但是請注意,我必須擁有兩個幾乎完全相同的控件。 在一個控件上,我需要綁定到VisibleAtHome,並在另一個上綁定到VisibleAtRestaurant。 擁有一個控件會很好。

我可以想到一些可能的改進。

  1. 也許可以只使用1個控件並在運行時更改綁定。 這是有好處的,但是鑒於有問題的屬性位於可能反過來位於集合中的集合內部,因此我認為可能很難做到(記住,我正在提供一個簡化的示例)。

  2. 也許在我的模型類中,我可以只擁有“ Visible”屬性,並根據需要在VisibleAtHome或VisibleAtRestaurant中讀取。 請參見我可以在運行時將屬性添加到對象屬性嗎? 有關如何完成此操作的信息,但是請注意,我當前的處理方式是,將整個文件讀入模型,然后將整個模型保存回文件。 我不想因為我正在使用VisibleAtHome而丟失有關VisibleAtRestaurant的信息。

  3. 我可以有一個不可序列化的屬性“ Visible”,它根據傳遞給構造函數的內容返回VisibleAtHome或VisibleAtRestaurant。 不確定這樣做是否可行,因為在序列化/反序列化時需要無參數的構造函數(對嗎?)。 另外,Model類必須以某種方式告訴Widget類正在發生的事情。

有人對此有任何想法嗎? 同樣,我的目標是僅擁有(a)一個XML文件(實際上,這是必須的!),(b)一個模型類和(c)一個UserControl。 (d)我不想在任何地方都鍵入VisibleAtRestaurant和VisibleAtHome。 那是維護的噩夢。 我做了a)和b)。 現在我只需要c)和d)的幫助。 之所以出現這個問題,是因為我從一個僅需要在1個用戶控件中顯示的模型開始,並且(您猜到了),有人(老板)決定我們需要在大多數情況下都需要顯示該模型的情況下顯示模型。相同,但某些屬性可能具有不同的值,具體取決於您在哪里顯示模型。 我的“廚房”與“餐館”的想法是我試圖簡化和隱藏專有信息。

謝謝戴夫

PS,這是我的模型課:

 public class Model :  INotifyPropertyChanged
{
    public Model()
    {

    }
    private List<Widget> _widgets = new List<Widget>();

    [System.Xml.Serialization.XmlArray("Widgets"),
    System.Xml.Serialization.XmlArrayItem(typeof(Widget))]
    public Widget[] Widgets
    {
        get { return _widgets.ToArray(); }
        set
        {
            _widgets = new List<Widget>(value);//value;
            OnPropertyChanged("Widgets");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    /// <summary>
    /// Raises this object's PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The property that has a new value.</param>
    protected virtual void OnPropertyChanged(string propertyName)
    {

        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }
}


public class Widget :  INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get {
            return _name;
        }
        set 
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }

    // many more common properties in real case...

    private string _visibleAtHome;
    public string VisibleAtHome
    {
        get {
            return _visibleAtHome;
        }
        set 
        {
            if (_visibleAtHome != value)
            {
                _visibleAtHome = value;
                OnPropertyChanged("VisibleAtHome");
            }
        }
    }

    private string _visibleAtRestaurant;
    public string VisibleAtRestaurant
    {
        get {
            return _visibleAtRestaurant;
        }
        set 
        {
            if (_visibleAtRestaurant != value)
            {
                _visibleAtRestaurant = value;
                OnPropertyChanged("VisibleAtRestaurant");
            }
        }
    }

     public event PropertyChangedEventHandler PropertyChanged;
    /// <summary>
    /// Raises this object's PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The property that has a new value.</param>
    protected virtual void OnPropertyChanged(string propertyName)
    {

        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }
}

對家庭使用一個模型類,對餐廳使用另一個模型類,並擺脫VisibleAt這個元素。 假設您應該添加另一個實體,例如食品博覽會,則只需為其創建另一個模型類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM