2009-11-23 19 views
2

Winforms .net 3.5 app。在我的应用我有一个泛型类,看起来像这样:Winforms中的ObservableCollection <T>以及可能的备选方案

public class FilterItem { 
    public FilterItem() { } 
    public string FilterProperty { get; set; } 
    public bool FilterPropertyChecked { get; set; } 
    public ComparitiveOperator FilterOperator { get; set; } 
    public string FilterValue { get; set; } 
} 

我用它在我所有的对话框时,我想实现某种过滤功能。所以我把这个对话框称为在构造函数中传递的预先拼接的List<FilterItem>。现在,当对话框加载时,它遍历每个直通列表项,并增加了:

  1. 一个复选框
  2. 一个ComboBox
  3. 一个TextBox

在一个TableLayoutPanel中的每一行。复选框的文本属性为FilterProperty,其检查状态为FilterPropertyChecked ...组合框从FilterOperator获得绑定...并且文本框的文本值为FilterValue

注意如何我只说得到。我想要做的是自动更新这些属性,当它们的属性被绑定的控件改变时。我听说过ObservableCollection<T>,但是在添加System.Collections.ObjectModel命名空间后,我似乎没有在Winforms中“访问”它。

什么是最好的方式来实现这一点。 BindingList与INotifyPropertyChanged?我不是后者的专家,并且非常感谢一些提示 - 如果这是我应该去的方式。

谢谢你!

编辑:

好吧,让我来发布一些代码来显示什么,我认为我应该做的:)。我知道我需要实现INotifyPropertyChanged我的FilterItem类,所以(只为FilterValue部分为例):

public class FilterItem : INotifyPropertyChanged { 
    public FilterItem() { } 
    public string FilterProperty { get; set; } 
    public bool FilterPropertyChecked { get; set; } 
    public ComparitiveOperator FilterOperator { get; set; } 

    private string _FilterValue; 
    public string FilterValue { 
     get { return this._FilterValue; } 
     set { 
      if (this._FilterValue != value) { 
       this._FilterValue = value; 
       this.OnFilterValueChanged(); 
      } 
     } 
    } 

    #region INotifyPropertyChanged Members 
    protected void OnFilterValueChanged() { 
     var handler = this.PropertyChanged; 
     if (handler != null) { 
      handler(this, new PropertyChangedEventArgs("FilterValue")); 
     } 
    } 
    public event PropertyChangedEventHandler PropertyChanged; 
    #endregion 
} 

现在应该都在我的Form_Load走到一起(这仅仅是文本框部分,我省略了,像这样的Checbox和ComboBox):

private List<FilterItem> FilterList; // <-- this gets assigned to in the constructor 

private void dlgFilterData_Load(object sender, EventArgs e) { 
    foreach (FilterItem item in FilterList) { 
     txt = new TextBox(); 
     txt.DataBindings.Add("Text", item, "FilterValue", false, DataSourceUpdateMode.OnPropertyChanged); 
     txt.Dock = DockStyle.Fill; 
    } 
} 

文本框的数据绑定数据源是的FilterItem“项”。但是现在我的视觉工作室IDE似乎遇到了问题,所以无法尝试,但是在启动并运行时会出现问题。我现在想知道的是:将这种设置成功帮助让我个人FilterItem s到时得到的分配控制的各个属性的更改自动更新?

+0

我是否也应该使用BindingList 而不是普通列表? – Shalan

回答

3

的的ObservableCollection类是WindowsBase组装,所以你需要WindowsBase添加到项目中提到的“访问”了。

话虽这么说,我不认为是的ObservableCollection想给你你想要的一切。当您添加或删除项目时,您的绑定控件会收到通知,但没有自动属性更改通知,这听起来就像您想要的。

无论你最终使用什么类型的集合,我认为你在INotifyPropertyChanged的正确轨道上。下面是实现INotifyPropertyChanged的一个简单的例子:

class Foo : INotifyPropertyChanged 
{ 
    #region Bar property 

    private string _bar; 
    public string Bar 
    { 
     get { return _bar; } 
     set 
     { 
      if (_bar != value) 
      { 
       _bar = value; 

       OnPropertyChanged("Bar"); 
      } 
     } 
    } 

    #endregion 

    protected void OnPropertyChanged(string name) 
    { 
     var handler = PropertyChanged; 

     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(name)); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

基本上,任何时候你的对象更改的属性,火PropertyChanged事件,通过更改属性的名称。

最后,所有这些都可能是没有实际意义的,因为你说你想改变对象属性的值来响应绑定到该属性的控件的更改。通常的Windows Forms数据绑定基础结构可以在没有INotifyPropertyChanged或任何其他接口的帮助下实现。如果您需要从其他位置通知绑定控件更改对象属性,则只需实现INotifyPropertyChanged。

+0

丹尼尔,非常感谢你的回复和代码! 针对上述情况,林先生并不太确定,我完全理解你的最后一句话 - 请你澄清一下吗?另外,我是在正确的轨道与文本框数据绑定,并使用BindingList而不是列表? (对不起,我的VS IDE仍在眨眼,但我认为它的一大堆愚蠢的加载项导致它崩溃,现在将其删除,所以希望能有机会测试所有这些)。 – Shalan

+1

在对象和控件之间建立双向数据绑定(正常情况)时,框架将尝试更新一个以响应另一个对象的更改。数据绑定框架已经知道如何检测内置控件的属性何时发生变化,因此它可以在没有任何进一步帮助的情况下更改数据源对象的绑定属性。另一方面,如果您正在代码中更改数据源对象的属性值,则框架不知道如何检测该属性(并更新绑定控件),除非您正确实现INotifyPropertyChanged。 –

+1

关于使用BindingList vs List:考虑到你如何构建表单,它没有任何区别。如果将FilterItem对象的集合直接绑定到网格或列表框之类的东西,那么BindingList将使得向集合添加项目会将相同的项目添加到网格/列表框,反之亦然。 –

相关问题