2014-01-16 53 views
1

我有一個ListBox,它的DataSource是一個BindingSource。 BindingSource的DataSource是我寫的實現IList < T>的自定義類。當用戶在列表中輸入新項目的數據時,我通過用新項目調用BindingSource.Insert()來更新BindingSource。這將項目添加到列表框,但它似乎不修改作爲BindingSource的DataSource的基礎列表。BindingSource在插入時不修改其DataSource

當我嘗試使用普通列表< T>而不是我的自定義IList類(FilteredList < T>)執行相同的操作時,列表將被BindingSource更新。所以問題似乎在於我的自定義類。但是我已經在FilteredList中的每個方法上都放了斷點,除了構造函數之外,它們都沒有被調用。所以我很難過。

在這裏,作爲參考,爲FilteredList < T>的代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace AmesView.Encapsulation 
{ 
    public class FilteredList<T>: IList<T> 
    { 
     public delegate bool TestMethod<T>(T item); 

     private IList<T> _innerList; 

     private TestMethod<T> _test; 

     public FilteredList(IList<T> innerList, TestMethod<T> test) 
     { 
      if (innerList == null) 
      { 
       throw new ArgumentException("innerList must not be null"); 
      } 
      if (test == null) 
      { 
       throw new ArgumentException("test must not be null"); 
      } 
      _innerList = innerList; 
      _test = test; 
     } 

     public int IndexOf(T item) 
     { 
      int count = 0; 
      foreach (T tmp in _innerList) 
      { 
       if (_test(tmp)) 
       { 
        if (item.Equals(tmp)) 
        { 
         break; 
        } 
        count++; 
       } 
      } 
      return count; 
     } 

     public void Insert(int index, T item) 
     { 
      int count = 0; 
      int allidx = 0; 
      foreach (T tmp in _innerList) 
      { 
       if (_test(tmp)) 
       { 
        if (count == index) 
        { 
         _innerList.Insert(allidx, item); 
         return; 
        } 
        count++; 
       } 
       allidx++; 
      } 
     } 

     public void RemoveAt(int index) 
     { 
      int count = 0; 
      int allidx = 0; 
      foreach (T tmp in _innerList) 
      { 
       if (_test(tmp)) 
       { 
        if (count == index) 
        { 
         _innerList.RemoveAt(allidx); 
         return; 
        } 
        count++; 
       } 
       allidx++; 
      } 
     } 

     public T this[int index] 
     { 
      get 
      { 
       int count = 0; 
       int allidx = 0; 
       foreach (T tmp in _innerList) 
       { 
        if (_test(tmp)) 
        { 
         if (count == index) 
         { 
          return _innerList[allidx]; 
         } 
         count++; 
        } 
        allidx++; 
       } 
       return default(T); 
      } 
      set 
      { 
       int count = 0; 
       int allidx = 0; 
       foreach (T tmp in _innerList) 
       { 
        if (_test(tmp)) 
        { 
         if (count == index) 
         { 
          _innerList[allidx] = value; 
         } 
         count++; 
        } 
        allidx++; 
       } 
      } 
     } 

     public void Add(T item) 
     { 
      _innerList.Add(item); 
     } 

     public void Clear() 
     { 
      _innerList.Clear(); 
     } 

     public bool Contains(T item) 
     { 
      foreach (T tmp in _innerList) 
      { 
       if (tmp.Equals(item) && _test(tmp)) 
       { 
        return true; 
       } 
      } 
      return false; 
     } 

     public void CopyTo(T[] array, int arrayIndex) 
     { 
      int count = 0; 
      foreach (T tmp in _innerList) 
      { 
       if (_test(tmp)) 
       { 
        int idx = arrayIndex + count; 
        if (idx < array.Length) 
        { 
         array[idx] = tmp; 
        } 
        count++; 
       } 
      } 
     } 

     public int Count 
     { 
      get 
      { 
       int count = 0; 
       foreach (T tmp in _innerList) 
       { 
        if (_test(tmp)) 
        { 
         count++; 
        } 
       } 
       return count; 
      } 
     } 

     public bool IsReadOnly 
     { 
      get 
      { 
       return _innerList.IsReadOnly; 
      } 
     } 

     public bool Remove(T item) 
     { 
      return _innerList.Remove(item); 
     } 

     public IEnumerator<T> GetEnumerator() 
     { 
      foreach (T tmp in _innerList) 
      { 
       if (_test(tmp)) 
       { 
        yield return tmp; 
       } 
      } 
     } 

     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
     { 
      foreach (T tmp in _innerList) 
      { 
       if (_test(tmp)) 
       { 
        yield return tmp; 
       } 
      } 
     } 
    } 
} 

回答

0

這似乎是BindingSource的類的預期行爲。查看該BindingSource.DataSource財產微軟的文檔中的備註部分:

http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.datasource%28v=vs.110%29.aspx

因爲數據源可以設置成許多不同類型的對象,有多種類型的自定義行爲。對於類型爲List < T>的DataSource的行爲顯然是將列表< T>包裝在BindingList < T>中,而其他實現IEnumerable < T>的類的行爲是創建一個新的BindingList < T>,其中來自IEnumerable < T>的項目被複制。因爲我的FilteredList < T>類沒有從List < T繼承,所以它得到了「不太特別的待遇」,並且作爲通用IEnumerable處理,而不是列表< T>。不幸的是,爲我的目的,但可以理解。

自從來到這個結論,我無意中發現了另一個有價值的信息比特:如果您創建的BindingList < T>自己,傳遞一個IList < T>的構造函數,然後分配這個的BindingList < T>的數據源你的BindingSource的屬性,一切工作和對BindingSource所做的更改都反映在原始列表中。