2009-07-24 7 views
1

Ich versuche, das .NET 2.0 ApplicationSettings-Feature zum ersten Mal zu verwenden, und finde es ein wenig ... rätselhaft in mancher Hinsicht. Ich hoffe, dass mir jemand helfen kann, herauszufinden, wo ich falsch liege.Aktualisieren gebundener Steuerelemente zu ApplicationSettings

Ich habe eine generische Einstellungs-Klasse, die ich implementiert habe, die eine Unterklasse von ApplicationSettingsBase ist. Ich habe eine Eigenschaft implementiert und markiert. Dies scheint zu funktionieren

Ich habe dann versucht, ein Listbox-Steuerelement an die Eigenschaft zu binden, und dies scheint auch zu funktionieren. Wenn ich das Formular öffne, lädt es die Eigenschaften gut.

Das Problem, das ich renne ist, dass, wenn ich die Einstellungen und Datenbindung aktualisieren möchte, ohne das Formular neu zu laden, es scheint nicht zu funktionieren. Es gibt keine Methoden, um die Bindung zu aktualisieren, und von was ich lese, sollte es nur automatisch aktualisieren (ApplicationSettingsBase implementiert IPropertyChangeNotify, die DataBindings abonnieren sollte .. aber es scheint nicht zu funktionieren). Sie können die Listbox auch nicht manuell aktualisieren, wenn Sie über eine DataBinding verfügen.

Also hier ist mein Code:

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

Mein Verständnis ist, dass etwas zu den Application Hinzufügen des IPropertyChangedNotify Feuer sollte die Kontrolle alarmieren Bindung, dass die Eigenschaft geändert wurde, und erzwingen Sie es neu zu laden .. aber das scheint nicht zu geschehen.

Was fehlt mir?

EDIT:

Ich glaube, ich weiß, was das Problem ist. Das Problem ist, dass ich die Inhalte der Sammlung in der Settings-Klasse ändere, aber nicht die eigentliche Eigenschaft selbst ändere (was die Sammlung selbst ist). Ich denke, dass ich wirklich die gesamte Sammlung hinzufügen oder entfernen müsste, um das IPropertyChangedNotify auszulösen, das nicht geschieht.

Ich bin mir nicht sicher, was die Lösung für dieses Problem ist.

Antwort

1

Sie müssen die Einstellung speichern und erneut zu laden:

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

ich mit bearbeiten und Ihren Kommentar zustimmen. Versuchen Sie stattdessen, eine BindingList zu verwenden.

Beispiel:

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

Das ist keine gute Option, weil es die Möglichkeit zum Abbrechen ohne Speichern von Einstellungen zerstört. Ich möchte nur Save() aufrufen, wenn ich Apply oder OK drücke. –

+0

Doh! Dies ist eines der Probleme mit .NET, es ist so riesig, dass man dieses Zeug manchmal nicht finden kann ... 4 Stunden mit der Problemumgehung auf der Toilette mit der Lösung, für die es bestimmt ist ... –

0

Ok, nicht eine große Lösung, und ich bin der Hoffnung, jemand hat man besser, aber das funktioniert:

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

ich einfach versucht, sich selbst neu zuzuweisen, aber es gibt anscheinend einige Optimierungen, die dies erkennen und das PropertyChanged nicht auslösen können.

Ich wäre mehr als glücklich, jemanden zu antworten, der eine bessere Lösung hat.

EDIT:

Ok, ich glaube, ich habe eine akzeptable Lösung gefunden, die nur ein wenig kludgey ist, und erfordert nicht die Schaffung neuer Objekte wie die ohne Grund oben.

Ok, zuerst, ich eine neue Methode, um meine Settings-Klasse hinzufügen:

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

Dies ermöglicht es mir ein Property Ereignis auszulösen, ohne tatsächlich die Eigenschaft zu ändern. Allerdings ist die Binding-Klasse für mich immer noch etwas zu schlau, weil sie weiß, dass sich die Eigenschaft nicht wirklich geändert hat .. also tut es nichts. So

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

, täuscht dieser Code die Binding-Klasse aus, indem Sie die Datasource-Clearing kann jetzt nicht sagen, dass das Objekt nicht geändert hat, so ist es die neueste Version der Daten zu ziehen hat. Ich kann damit leben, obwohl es immer noch ein bisschen stinkig ist.

EDIT2:

Wie drs weist darauf hin, sollte ich eine Binding verwendet haben, anstatt eine Liste, eine Binding verwendet, ist die richtige Lösung.

Verwandte Themen