2009-11-23 32 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將使得向集合添加項目會將相同的項目添加到網格/列表框,反之亦然。 –

相關問題