2011-10-07 36 views
9

Tôi đang cố gắng lưu trữ một bộ sưu tập các đối tượng tùy chỉnh trong Cài đặt ứng dụng.Gặp sự cố khi lưu tập hợp các đối tượng trong Cài đặt ứng dụng

Với một số sự giúp đỡ từ this related question, đây là những gì tôi hiện có:

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

Trong thiết kế Settings.settings tôi đã thêm tài sản của loại PeopleHolder qua nút trình duyệt, và thiết lập các phạm vi để 'Người dùng'. Phương thức Save() dường như hoàn tất thành công, không có thông báo lỗi, nhưng mỗi lần tôi khởi động lại các thiết lập ứng dụng không được duy trì.

Mặc dù không được hiển thị trong đoạn mã trên, tôi vẫn có thể duy trì các chuỗi, chứ không phải bộ sưu tập tùy chỉnh của tôi (tôi nhận thấy trong các câu hỏi tương tự khác trên SO có thể có vấn đề với số phiên bản. Tôi muốn loại trừ đó là thủ phạm có thể.)

Bất kỳ ý tưởng nào? Tôi chắc chắn có một cách rất đơn giản để làm điều này mà tôi chỉ thiếu :).

Cảm ơn sự giúp đỡ của bạn!

Trả lời

10

Tôi đã tìm ra nó nhờ this question!

Như đã đề cập trong câu hỏi mà tôi thêm này để 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; 
     } 
    } 

Và sau đó tất cả tôi cần là đoạn mã sau:

[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

Cảm ơn giải pháp đơn giản như vậy. Làm việc tuyệt vời cho tôi! – Seekeer

+0

+1 - Hoạt động như một sự quyến rũ. Cảm ơn. :) –

+0

+1 Vâng, nó hoạt động cho tôi trong tình huống tương tự quá. Nhưng có lẽ bạn đã đưa ra giải pháp thanh lịch hơn không phải thiết lập hack. Designer.cs? – beduin

3

Nếu bạn thêm ObservableCollection<People> để bạn mã riêng, nhưng chỉ định không gian tên "Thuộc tính", bạn có thể thực hiện thay đổi này mà không thay đổi cài đặt.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; 
      } 
     } 
    } 
} 

Xin lưu ý, tôi đã thay đổi khả năng truy cập của lớp Settings thànhpublic. (Có lẽ tôi không cần phải làm điều đó).

Nhược điểm duy nhất tôi thấy trong toàn bộ giải pháp/câu trả lời này là bạn không còn có thể thay đổi cài đặt cấu hình ứng dụng bằng hộp thoại Project -> Properties. Làm như vậy sẽ nghiêm túc làm hỏng cài đặt mới của bạn bằng cách chuyển đổi bạn đặt thành chuỗi và xâu chuỗi các thẻ XML của bạn.

Vì tôi muốn sử dụng một tệp cấu hình trên toàn hệ thống thay vì tệp người dùng cụ thể, tôi cũng đã thay đổi global::System.Configuration.UserScopedSettingAttribute()] thành [global::System.Configuration.ApplicationScopedSetting()]. Tôi rời khỏi người truy cập set trong lớp học, nhưng tôi biết rằng nó không thực sự tiết kiệm.

Cảm ơn bạn đã trả lời! Nó làm cho mã của tôi sạch hơn và dễ quản lý hơn nhiều.

+0

Cảm ơn rất nhiều về mẹo này. Tôi đã mất các thay đổi mà tôi đã thực hiện đối với Settings.Designer.cs – thowa

Các vấn đề liên quan