Winforms中的ObservableCollection <t>和可能的替代方案</t>

时间:2009-11-23 01:10:18

标签: winforms observablecollection inotifypropertychanged

Winforms .net 3.5 app。在我的应用程序中,我有一个类似的泛型类:

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. 组合框
  3. 文本框
  4. 到TableLayoutPanel中的每一行。 Checkbox从FilterProperty获取其文本属性,并从FilterPropertyChecked获取其Checked状态... Combobox从FilterOperator获取其绑定...并且Textbox从{{1获取文本值}}

    请注意我只是说 获取 。我想要做的是当绑定其属性的控件发生更改时自动更新这些属性。我听说过FilterValue,但在添加ObservableCollection<T>命名空间后,我似乎无法在Winforms中“访问”它。

    实现这一目标的最佳方式是什么? BindingList与INotifyPropertyChanged?我不是后者的专家,非常感谢一些指针 - 如果这是我应该去的方式。

    谢谢你!

    编辑:

    好的,让我发布一些代码来展示我认为我应该做的事情:)。我知道我需要在我的FilterItem类上实现System.Collections.ObjectModel,所以(例如,仅针对FilterValue部分):

    INotifyPropertyChanged

    现在它应该所有在我的Form_Load中聚集在一起(这只是Textbox部分,我省略了Checbox和ComboBox),如下所示:

    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
    }
    

    文本框的数据绑定DataSource是FilterItem'item'。但是现在我的Visual Studio IDE似乎遇到了问题,所以无法尝试这一点,但是当我启动并运行它时。我现在想知道的是:这个设置是否会成功帮助我的个人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; } } 在其指定的Control的相应属性发生变化时自动更新?

1 个答案:

答案 0 :(得分: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窗体数据绑定基础结构可以在没有INotifyPropertyChanged或任何其他接口的帮助下实现。如果需要从其他地方通知绑定控件对象属性的更改,则只需要实现INotifyPropertyChanged。