为什么我的ObservableCollection序列化不起作用?

时间:2012-09-01 07:33:04

标签: c# .net wpf xml xml-serialization

我正在尝试序列化和反序列化此ObservableCollection:

public class DataCollection : ObservableCollection<Data>
{
}

public class Data : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool? _enabled;

    public string Name { get; set; }
    public bool? Enabled 
    {
        get { return _enabled; }
        set { _enabled = value; NotifyPropertyChanged("Enabled"); }
    }

    public Data(string name, bool? enabled)
    {
        this.ScriptName = name;
        this.Enabled = enabled;
    }

    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}

使用此类(如What is the easiest way to save an Observable collectin of object to an XML file?示例中所示):

class UserPreferences
{
    private DataCollection _dataLst;
    private const string _dataLstFileName = "Data.xml";

    public DataCollection DataLst { get { return _dataLst; } set { _dataLst = value; } }

    public UserPreferences()
    {
        Load();
    }

    public void Load()
    {
        if (File.Exists(_dataLstFileName))
        {
            using (var reader = new StreamReader(_dataLstFileName))
            {
                var xs = new XmlSerializer(typeof(DataCollection));
                _dataLst = (DataCollection) xs.Deserialize(reader);
            }
        }
        else
        {
            _dataLst = new DataCollection();
        }
    }

    public void Save()
    {
        using (var writer = new StreamWriter(_dataLstFileName))
        {
            var xs = new XmlSerializer(typeof(DataCollection));
            xs.Serialize(writer, _dataLst);
        }
    }
}

以下是我从我的应用程序中调用它的方式:

public partial class MainWindow : Window
{
    private DataCollection DataLst;

    ...

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        var userPrefs = new UserPreferences();

        userPrefs.DataLst = DataLst; // DataList isn't null and contains correct data
        userPrefs.Save(); 
    }
}

但它会创建空文件并挂起(即使没有例外,只是应用程序窗口变黑并且没有响应)行

var xs = new XmlSerializer(typeof(DataCollection));  

2 个答案:

答案 0 :(得分:5)

经过一些研究后,似乎在序列化ObservableCollection<T>时出现问题。有关详细信息,请参阅this博文。

总结:

  

问题是事件尚未标记为非序列化。因此,每当您尝试序列化ObservableCollection的实例时,您还将尝试序列化任何事件处理程序。当您将集合用于其主要场景(数据绑定)时,您将为事件附加WPF控件。

     

(Kent Boogaart)

你的Data课程也会遇到类似的问题;像这样更新你的PropertyChanged事件:

[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;

除了其他人已经提到的更新外,您的Data课程也应标记为Serializable

答案 1 :(得分:3)

  1. 您的Data类必须具有参数less constructor,否则XmlSerializer将永远无法创建数据实例。
  2. 您应该存储和检索Data [],而不是存储DataCoollection,而不必执行任何其他操作。
  3. 存储时,可以调用ToArray方法获取Data []并使用typeof(Data [])进行序列化。
  4. 阅读时,您可以阅读数组并将项目添加到您的收藏中。