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

时间:2022-08-23 12:06:55

I'm trying to serialize and deserialize this ObservableCollection:

我正在尝试序列化和反序列化此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));
    }
}

Using this class (as in the What is the easiest way to save an Observable collectin of object to an XML file? example):

使用此类(如将对象的Observable collectin保存到XML文件的最简单方法是什么?示例):

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);
        }
    }
}

And here is how I call it from my app:

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

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(); 
    }
}

But it creates empty file and hangs up (even without exceptions, just app window becomes black and doesn't response) in the line

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

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

2 个解决方案

#1


3  

  1. Your Data class must have a parameter less constructor, otherwise XmlSerializer will never be able to create instance of Data.
  2. 您的Data类必须具有参数less constructor,否则XmlSerializer将永远无法创建Data实例。

  3. Instead of storing DataCoollection, you should store and retrieve Data[], it's easier without having to do anything else.
  4. 您应该存储和检索Data [],而不是存储DataCoollection,而不必执行任何其他操作。

  5. While storing, you can call ToArray method to get Data[] and use typeof(Data[]) for serializer.
  6. 存储时,可以调用ToArray方法获取Data []并使用typeof(Data [])进行序列化。

  7. While reading you can read the array and add items into your collection.
  8. 阅读时,您可以阅读数组并将项目添加到您的收藏中。

#2


5  

After a little research it seems that there are problems when serializing ObservableCollection<T>. See this blog post for more information.

经过一些研究后,似乎在序列化ObservableCollection 时存在问题。有关更多信息,请参阅此博客文章。

In summary:

The problem is that the events have not been marked as non-serialized. Therefore, whenever you try to serialize an instance of ObservableCollection, you will also be attempting to serialize any event handlers. When you're using the collection for its primary scenario (data binding), you will have WPF controls attached to the events.

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

(Kent Boogaart)

Your Data class will also suffer from similar problems; update your PropertyChanged event like so:

您的数据类也会遇到类似的问题;像这样更新你的PropertyChanged事件:

[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;

As well as the updates already mentioned by other people, your Data class should also be marked as Serializable.

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

#1


3  

  1. Your Data class must have a parameter less constructor, otherwise XmlSerializer will never be able to create instance of Data.
  2. 您的Data类必须具有参数less constructor,否则XmlSerializer将永远无法创建Data实例。

  3. Instead of storing DataCoollection, you should store and retrieve Data[], it's easier without having to do anything else.
  4. 您应该存储和检索Data [],而不是存储DataCoollection,而不必执行任何其他操作。

  5. While storing, you can call ToArray method to get Data[] and use typeof(Data[]) for serializer.
  6. 存储时,可以调用ToArray方法获取Data []并使用typeof(Data [])进行序列化。

  7. While reading you can read the array and add items into your collection.
  8. 阅读时,您可以阅读数组并将项目添加到您的收藏中。

#2


5  

After a little research it seems that there are problems when serializing ObservableCollection<T>. See this blog post for more information.

经过一些研究后,似乎在序列化ObservableCollection 时存在问题。有关更多信息,请参阅此博客文章。

In summary:

The problem is that the events have not been marked as non-serialized. Therefore, whenever you try to serialize an instance of ObservableCollection, you will also be attempting to serialize any event handlers. When you're using the collection for its primary scenario (data binding), you will have WPF controls attached to the events.

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

(Kent Boogaart)

Your Data class will also suffer from similar problems; update your PropertyChanged event like so:

您的数据类也会遇到类似的问题;像这样更新你的PropertyChanged事件:

[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;

As well as the updates already mentioned by other people, your Data class should also be marked as Serializable.

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