2011-10-07 15 views
9

Próbuję zapisać kolekcję niestandardowych obiektów w Ustawieniach aplikacji.Rozwiązywanie problemów z kolekcją obiektów w Ustawieniach aplikacji

Z pomocą this related question, tutaj jest to, co aktualnie mam:

// 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()); 
    } 
} 

w projektancie Settings.settings dodałem właściwość typu PeopleHolder za pomocą przycisku przeglądarki i ustawić zakres na „Użytkownik”. Wydaje się, że metoda Save() zakończyła się pomyślnie, nie ma komunikatów o błędach, ale za każdym razem, gdy ponownie uruchamiam ustawienia aplikacji, nie są one zachowywane.

Chociaż nie jest pokazany w powyższym kodzie, jestem w stanie utrzymać ciągi Strings, po prostu nie mój zbiór niestandardowy (zauważyłem w innych podobnych pytaniach na SO może czasami być problem z numerami wersji, który zapobiega zapisywaniu ustawień podczas debugowania, więc Chcę wykluczyć, że jako ewentualny winowajca.)

Wszelkie pomysły? Jestem pewien, że jest bardzo prosty sposób na zrobienie tego, czego mi brakuje.

Dzięki za pomoc!

Odpowiedz

10

Wyliczyłem to dzięki this question!

Jak sugeruje w tej kwestii dodałem to do 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; 
     } 
    } 

A potem wszystko, czego potrzebowałem był następujący kod:

[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()); 
    } 
} 
+0

Dzięki za tak proste rozwiązanie. Działają doskonale dla mnie! – Seekeer

+0

+1 - Działa jak urok. Dzięki. :) –

+0

+1 Tak, to działa dla mnie w tej samej sytuacji. Ale może wymyśliłeś bardziej eleganckie rozwiązanie, które nie zawiera hakerskich ustawień.Designer.cs? – beduin

3

Jeśli dodać do listy ObservableCollection<People> własny kod, ale określ przestrzeń nazw "Właściwości", możesz wprowadzić tę zmianę bez zmiany ustawień. Projektant.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; 
      } 
     } 
    } 
} 

Uwaga: zmieniono dostępność klasy Settings napublic. (Prawdopodobnie nie musiałem tego robić).

Jedyną wadą tego rozwiązania/odpowiedzi jest to, że nie można już wprowadzać zmian w ustawieniach konfiguracji aplikacji za pomocą okna dialogowego Projekt -> Właściwości. W ten sposób poważnie zepsuć swoje nowe ustawienia, konwertując ustawienia na ciąg i zniekształcanie tagów XML.

Ponieważ chciałem użyć pojedynczego pliku konfiguracyjnego dla całego systemu zamiast pliku specyficznego dla użytkownika, zmieniłem także global::System.Configuration.UserScopedSettingAttribute()] na [global::System.Configuration.ApplicationScopedSetting()]. Zostawiłem dostęp do klasy set w klasie, ale wiem, że tak naprawdę nie zapisuje.

Dzięki za odpowiedź! Dzięki temu mój kod jest dużo bardziej przejrzysty i łatwiejszy w zarządzaniu.

+0

Wielkie dzięki za tę wskazówkę. Straciłem już moje zmiany wprowadzone w Settings.Designer.cs – thowa

Powiązane problemy