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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12225853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 05:10:44  来源:igfitidea点击:

Why my ObservableCollection serialization doesn't work?

c#.netwpfxmlxml-serialization

提问by Alex P.

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 对象集合保存到 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));  

采纳答案by Akash Kava

  1. Your Data class must have a parameter less constructor, otherwise XmlSerializer will never be able to create instance of Data.
  2. Instead of storing DataCoollection, you should store and retrieve Data[], it's easier without having to do anything else.
  3. While storing, you can call ToArray method to get Data[] and use typeof(Data[]) for serializer.
  4. While reading you can read the array and add items into your collection.
  1. 您的 Data 类必须有一个无参数构造函数,否则 XmlSerializer 将永远无法创建 Data 的实例。
  2. 您应该存储和检索 Data[],而不是存储 DataCoollection,它更容易,无需执行任何其他操作。
  3. 在存储时,您可以调用 ToArray 方法获取 Data[] 并使用 typeof(Data[]) 进行序列化。
  4. 在阅读时,您可以阅读数组并将项目添加到您的集合中。

回答by Benjamin Gale

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

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

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.

(Kent Boogaart)

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

(肯特·布加特)

Your Dataclass will also suffer from similar problems; update your PropertyChangedevent like so:

你的Data班级也会遇到类似的问题;PropertyChanged像这样更新您的活动:

[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;

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

除了其他人已经提到的更新之外,您的Data班级也应标记为Serializable.