2009-07-24 64 views
1

我试图第一次使用.NET 2.0 ApplicationSettings功能,并发现它有点...在某些方面令人费解。我希望有人能帮我弄清楚我哪里出错了。更新绑定控件到ApplicationSettings

我有一个通用设置类,我已经实现了这是ApplicationSettingsBase的一个子类。我已经实现了一个属性,并对其进行了标记。这似乎工作

我试图将一个列表框控件绑定到属性,这也似乎工作。当我打开表单时,它加载属性就好了。

我遇到的问题是,如果我想更新设置和数据绑定而不重新加载窗体,它似乎不工作。没有方法来刷新绑定,并从我正在阅读,它应该只是自动更新(ApplicationSettingsBase实现IPropertyChangeNotify,DataBindings应该订阅..但它似乎并没有工作)。如果您有DataBinding,您也不能手动更新列表框。

因此,这里是我的代码:

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

这不是一个好的选择,因为它破坏了不保存设置而取消的功能。我只想在应用或确定时调用Save()。 – 2009-07-24 01:44:40

0

好吧,不是一个很好的解决方案,而我希望有人有更好的一个,但这个工程:

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

我试图简单地重新分配自己本身,但显然在那里有一些优化,检测到这一点,并没有触发PropertyChanged。

我很乐意给出一个更好的解决方案的人的答案。

编辑:

好吧,我想我已经找到可接受的解决方案,这只是一个小k​​ludgey,并且不需要像上面无故新对象的创建。

好吧,首先,我添加了一个新的方法,以我的设置类:

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

这让我没有实际改变属性触发PropertyChanged事件。然而,对于我来说,Binding类仍然有点太聪明,因为它知道这个属性并没有真正改变......所以它什么也不做。

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

所以,这个代码假货了Binding类,通过清除数据源,现在不能告诉该属性没有改变,所以它有拉最新版本的数据。即使它仍然有点臭,我可以忍受这一点。

EDIT2:

由于DRS指出,我本来应该使用的BindingList,而不是一个列表,使用的BindingList是正确的解决方案。

相关问题