3

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

このクラスの使用(オブジェクトの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);
        }
    }
}

そして、これが私のアプリからそれを呼び出す方法です:

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

2 に答える 2

5

少し調べてみると、シリアル化するときに問題があるようですObservableCollection<T>。詳細については、このブログ投稿を参照してください。

要約すれば:

問題は、イベントが非シリアル化としてマークされていないことです。したがって、ObservableCollectionのインスタンスをシリアル化しようとすると、イベントハンドラーもシリアル化しようとします。コレクションを主要なシナリオ(データバインディング)に使用する場合、イベントにWPFコントロールがアタッチされます。

(ケント・ブオゴール)

あなたのDataクラスも同様の問題に苦しむでしょう。PropertyChanged次のようにイベントを更新します。

[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;

他の人がすでに言及した更新と同様に、Dataクラスもとしてマークする必要がありますSerializable

于 2012-09-01T08:03:27.907 に答える
3
  1. Dataクラスには、パラメーターの少ないコンストラクターが必要です。そうでない場合、XmlSerializerはDataのインスタンスを作成できません。
  2. DataCoollectionを保存する代わりに、Data []を保存および取得する必要があります。これは、他に何もしなくても簡単です。
  3. 保存中に、ToArrayメソッドを呼び出してData []を取得し、シリアライザーにtypeof(Data [])を使用できます。
  4. 読みながら、配列を読み、コレクションにアイテムを追加できます。
于 2012-09-01T08:01:28.170 に答える