2014-01-16 1 views
1

DataSource가 BindingSource 인 ListBox가 있습니다. BindingSource의 DataSource는 IList < T>를 구현 한 필자가 작성한 사용자 정의 클래스입니다. 사용자가 목록의 새 항목에 대한 데이터를 입력하면 BindingSource.Insert()를 새 항목으로 호출하여 BindingSource를 업데이트합니다. 이 경우 ListBox에 항목이 추가되지만 BindingSource의 DataSource 인 기본 목록은 수정하지 않는 것 같습니다.BindingSource가 삽입시 DataSource를 수정하지 않습니다.

내 사용자 지정 IList 클래스 (FilteredList < T>)가 아닌 일반 목록 < T>에서 동일한 작업을 수행하려고하면 목록이 BindingSource에 의해 업데이트됩니다. 그래서 문제는 내 커스텀 클래스에있는 것처럼 보입니다. 그러나 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에 클래스의 의도 된 동작 것으로 보인다 : 여기

는 참조 용 FilteredList < T>에 대한 코드이다. BindingSource.DataSource 속성에 마이크로 소프트의 설명서의 설명 부분을 참조 : 데이터 소스는 객체의 다양한 종류로 설정할 수 있습니다

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

때문에, 많은 종류의 사용자 지정 동작이있다. 목록 < T> 형식의 데이터 소스에 대한 동작은 BindingList <T>에 List < T>를 래핑하는 것 같습니다. 반면 IEnumerable <T>을 구현하는 다른 클래스의 동작은 새 BindingList < T>를 만드는 것입니다. IEnumerable < T>의 항목이 복사됩니다. 내 FilteredList < T> 클래스는 List < T>에서 상속하지 않았으므로 "덜 특별한 취급"을 받았으며 List < T>가 아닌 일반 IEnumerable < T>로 처리되었습니다. 불행한 것은 내 목적이지만 이해할 만하다.

이 결론에 오기 때문에, 나는 정보의 또 다른 유용한 비트에 발견 한 : 당신이> 사용자 스스로는 바인딩 < T를 만들 경우, 생성자에 IList의 < T>를 통과 한 후 데이터 소스이는 바인딩 < T>를 지정 BindingSource의 모든 속성이 작동하고 BindingSource에 대한 변경 내용이 원래 목록에 반영됩니다.

관련 문제