9

カスタム オブジェクトのコレクションをアプリケーション設定に保存しようとしています。

この関連する質問の助けを借りて、現在私が持っているものは次のとおりです。

// implementing ApplicationSettingsBase so this shows up in the Settings designer's 
// browse function
public class PeopleHolder : ApplicationSettingsBase
{
    [UserScopedSetting()]
    [SettingsSerializeAs(System.Configuration.SettingsSerializeAs.Xml)]
    public ObservableCollection<Person> People { get; set; }
}


[Serializable]
public class Person
{
    public String FirstName { get; set; }
}

public MainWindow()
{
    InitializeComponent();

    // AllPeople is always null, not persisting
    if (Properties.Settings.Default.AllPeople == null)
    {
        Properties.Settings.Default.AllPeople = new PeopleHolder()
            {
                People = new ObservableCollection<Person> 
                    { 
                        new Person() { FirstName = "bob" },
                        new Person() { FirstName = "sue" },
                        new Person() { FirstName = "bill" }
                    }
            };
        Properties.Settings.Default.Save();
    }
    else
    {
        MessageBox.Show(Properties.Settings.Default.AllPeople.People.Count.ToString());
    }
}

Settings.Settings Designer で、ブラウザー ボタンを使用して PeopleHolder タイプのプロパティを追加し、スコープを「ユーザー」に設定しました。Save() メソッドは正常に完了したようで、エラー メッセージは表示されませんが、アプリケーションを再起動するたびに設定が保持されません。

上記のコードには示されていませんが、カスタムコレクションではなく、文字列を永続化できます(SOに関する他の同様の質問で、デバッグ中に設定を保存できないバージョン番号に問題があることに気付いたので、ルールを適用したい可能性のある犯人としてそれをアウト.)

何か案は?私はこれを行うための非常に簡単な方法があると確信しています:)。

ご協力いただきありがとうございます!

4

2 に答える 2

10

この質問のおかげで私はそれを理解しました!

その質問で示唆されているように、私はこれをSettings.Designer.csに追加しました。

    [global::System.Configuration.UserScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public ObservableCollection<Person> AllPeople
    {
        get
        {
            return ((ObservableCollection<Person>)(this["AllPeople"]));
        }
        set
        {
            this["AllPeople"] = value;
        }
    }

そして、必要なのは次のコードだけでした。

[Serializable]
public class Person
{
    public String FirstName { get; set; }
}

public MainWindow()
{
    InitializeComponent();

    // this now works!!
    if (Properties.Settings.Default.AllPeople == null)
    {
        Properties.Settings.Default.AllPeople = new ObservableCollection<Person> 
        { 
            new Person() { FirstName = "bob" },
            new Person() { FirstName = "sue" },
            new Person() { FirstName = "bill" }
        };
        Properties.Settings.Default.Save();
    }
    else
    {
        MessageBox.Show(Properties.Settings.Default.AllPeople.People.Count.ToString());
    }
}
于 2011-10-07T00:54:31.003 に答える
3

を独自のコードに追加するObservableCollection<People>が、"Properties" 名前空間を指定する場合、settings.Designer.cs を変更せずにこの変更を行うことができます。

namespace MyApplication.Properties
{  
    public sealed partial class Settings
    {
        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public ObservableCollection<Person> AllPeople
        {
            get
            {
                return ((ObservableCollection<Person>)(this["AllPeople"]));
            }
            set
            {
                this["AllPeople"] = value;
            }
        }
    }
}

Settingsクラスのアクセシビリティを に変更したことに注意してください public(おそらくそれを行う必要はありませんでした)。

このソリューション/回答全体で見た唯一の欠点は、[プロジェクト] -> [プロパティ] ダイアログを使用してアプリケーション構成設定を変更できなくなったことです。これを行うと、設定が文字列に変換され、XML タグが壊れて、新しい設定が大幅に台無しになります。

ユーザー固有のファイルではなく、単一のシステム全体の構成ファイルを使用したかったためglobal::System.Configuration.UserScopedSettingAttribute()][global::System.Configuration.ApplicationScopedSetting()]. アクセサーをクラスに残しましたsetが、実際には保存されないことがわかっています。

答えてくれてありがとう!これにより、コードが非常にクリーンになり、管理が容易になります。

于 2013-03-06T19:56:41.973 に答える