2009-07-24 4 views
1

.NET 2.0のApplicationSettings機能を初めて利用しようとしていますが、これは少し難解です。誰かが私がどこに間違っているのか理解できるように助けてくれることを願っています。バインドされたコントロールをApplicationSettingsに更新する

私は実装した汎用設定クラスがApplicationSettingsBaseのサブクラスです。私はプロパティを実装してタグ付けしました。これはうまくいくようです

私はリストボックスコントロールをプロパティにバインドしようとしましたが、これも機能するようです。私がフォームを開くと、プロパティーがうまく読み込まれます。

私が問題になっているのは、フォームをリロードしないで設定やデータバインドを更新したい場合、動作していないようです。バインディングをリフレッシュするメソッドはありません。私が読んでいるものから、自動更新する必要があります(ApplicationSettingsBaseはIPropertyChangeNotifyを実装していますが、DataBindingsに登録する必要がありますが、動作していないようです)。また、データバインディングがある場合は、リストボックスを手動で更新することもできません。

だからここに私のコードです:

Settings.cs

public class Settings : ApplicationSettingsBase 
{ 
    public Settings() 
    { 
     if (FixedBooks == null) FixedBooks = new List<string>(); 
    } 

    [UserScopedSetting()] 
    public List<string> FixedBooks 
    { 
     get { return (List<string>)this["FixedBooks"]; } 
     protected set { this["FixedBooks"] = value; } 
    } 
} 

SettingsForm.cs

Settings _settings = new Settings(); 

private void SettingsForm_Load(object sender, EventArgs e) 
{ 
    lbFixedColumns.DataBindings.Add(new Binding("DataSource", _settings, 
     "FixedBooks", false, DataSourceUpdateMode.OnPropertyChanged)); 
} 

private void DoSomething() 
{ 
    _settings.FixedBooks.Add("Test"); 
} 

私の理解では、ApplicationSettingsに何かを追加すると、コントロールを警告するIPropertyChangedNotifyを発射すべきであるということですプロパティが変更されたことをバインドし、強制的にリロードします。しかし、これは起こっていないようです。

私には何が欠けていますか?

編集:

私は問題が何であるか知っていると思います。問題は、私はSettingsクラスのコレクションの内容を変更していますが、実際のプロパティ自体(コレクション自体)は変更していないということです。実際にIPropertyChangedNotifyを起動させるには、コレクション全体を実際に追加したり削除したりしなければならないと思いますが、これは起きていません。

この問題の解決方法はわかりません。

答えて

1

あなたは、設定を保存し、それをリロードする必要があります。

private void DoSomething() 
{ 
    _settings.FixedBooks.Add("Test"); 
    _settings.Save(); 
    _settings.Reload(); 
} 

私はあなたの編集、あなたのコメントに同意します。代わりにBindingListを使用してみてください。

例:

public class Settings : ApplicationSettingsBase 
{ 
    public Settings() 
    { 
     if (FixedBooks == null) FixedBooks = new BindingList<string>(); 
     FixedBooks.ListChanged += FixedBooks_ListChanged; 
    } 


    void FixedBooks_ListChanged(object sender, ListChangedEventArgs e) 
    { 
     this["FixedBooks"] = FixedBooks; 
    } 

    [UserScopedSetting()] 
    public BindingList<string> FixedBooks 
    { 
     get { return (BindingList<string>)this["FixedBooks"]; } 
     protected set { this["FixedBooks"] = value; } 
    } 
} 
+0

これは、設定を保存せずにキャンセルする機能を無効にするため、適切ではありません。私はApplyまたはOKを押すとSave()を呼び出すだけです。 –

+0

Doh!これは.NETの問題の1つですが、それは非常に巨大で、時にはこのようなものを見つけることができません...解決策が見つかってから4時間が経過しました。 –

0

優れたソリューション、OKではない、と私は誰かがよりよいものを持っているが、これは動作します願っています:、

private void DoSomething() 
{ 
    _settings.FixedBooks.Add("Test");  
    var old = _settings.FixedBooks; 
    _settings["FixedBooks"] = new List<string>(); 
    _settings["FixedBooks"] = old; 
} 

私は単に自分自身に自分自身を再割り当てしようとしました明らかに、これを検出してPropertyChangedを起動しない最適化がいくつかあります。

もっと良い解決策を思いついた人に答えてもらいたいと思っています。

EDIT:

[OK]を、私は私が少しだけkludgeyだ受け入れ可能な解決策を見つけた、と理由もなく上記のような新しいオブジェクトの作成を必要としないと思います。

[OK]を、最初に、私は私の設定のクラスに新しいメソッドを追加します。これは私が実際にプロパティを変更することなく、PropertyChangedイベントをトリガすることができます

public void FirePropertyChanged(string propertyName) 
{ 
    PropertyChangedEventArgs args2 = new PropertyChangedEventArgs(propertyName); 
    OnPropertyChanged(this, args2); 
} 

。しかし、Bindingクラスは、プロパティが実際には変更されていないことを知っているので、私にとってはややスマートです。何もしません。

private void DoSomething() 
{ 
    _settings.FixedBooks.Add("Test"); 
    lbFixedColumns.DataSource = null; 
    _settings.FirePropertyChanged("FixedBooks"); 
} 

ので、このコードは、それが今では、データの最新バージョンを引っ張って持っているので、プロパティは、変更されていないことを伝えることができないデータソースをクリアすることによって、Bindingクラスを偽装。私はまだこれは少し臭いですが、これで生きることができます。

EDIT2:DRSが指摘するように

、私はするBindingListが正解である使用して、するBindingListではなく、リストを使用している必要があります。

関連する問題