2011-03-24 1 views
2

에 따라 나는 매우 간단한 클래스가 PeopleList <>이라는 People 클래스. PeopleList <>은이 클래스의 인스턴스를 DataGridView에 직접 바인딩하기 때문에 특별합니다. 일반적으로 IList <>을 datagridview (DGV)의 데이터 소스로 사용하지 마십시오. IList는 ListChanged 이벤트를 생성하지 않습니다. 즉, DGV를 IList에 바인딩하면 <> 행 수 DGV가 설정됩니다. 즉, IList <>에 새 항목이 추가되면 DGV에 표시되지 않습니다. 이 작업을 수행하는 유일한 방법은 DGV의 데이터 소스를 null로 설정 한 다음 변경 후 IList <>에 리 바인드하는 것입니다.C#을 업데이트 된 DataGridView IList의

는 바인딩이 훨씬 더 적합 필요성이 유형이지만, 슬프게도, 나는 로 갈 수없는 이유는 내가 인터페이스 같은 IList의 <>를 사용하는 것이 필수적이다. 이 문제를 해결하기 위해 IList <> 인터페이스의 구현에 ListChanged 이벤트를 통합하는 일부 코드를 발견했지만 일부 문제가 있습니다. 이 코드로도 이벤트 핸들러 메서드가 있어야 할 것 같습니다. 그리고 어느 시점에서이 메서드를 ListChanged 이벤트의 핸들러로 선언해야합니다. 보라 :

class PeopleList<T> : IList<T> 
    { 
     private IList<T> internalList; 

    public class ListChangedEventArgs : EventArgs { 
     public int index; 
     public T item; 
     public ListChangedEventArgs(int index, T item) { 
     this.index = index; 
     this.item = item; 
     } 
    } 

    public delegate void ListChangedEventHandler(object source, ListChangedEventArgs e); 
    public delegate void ListClearedEventHandler(object source, EventArgs e); 
    public event ListChangedEventHandler ListChanged; 
    public event ListClearedEventHandler ListCleared; 

    public PeopleList() { 
     internalList = new List<T>(); 
    } 

    public PeopleList(IList<T> list) { 
     internalList = list; 
    } 



    public PeopleList(IEnumerable<T> collection) { 
     internalList = new List<T>(collection); 
    } 

    protected virtual void OnListChanged(ListChangedEventArgs e) { 
     if (ListChanged != null) 
     ListChanged(this, e); 
    } 

    protected virtual void OnListCleared(EventArgs e) { 
     if (ListCleared != null) 
     ListCleared(this, e); 
    } 

    public int IndexOf(T item) { 
     return internalList.IndexOf(item); 
    } 

    public void Insert(int index, T item) { 
     internalList.Insert(index, item); 
     OnListChanged(new ListChangedEventArgs(index, item)); 
    } 

    public void RemoveAt(int index) { 
     T item = internalList[index]; 
     internalList.Remove(item); 
     OnListChanged(new ListChangedEventArgs(index, item)); 
    } 

    T this[int index] { 
     get { return internalList[index]; } 
     set { 
      internalList[index] = value; 
      OnListChanged(new ListChangedEventArgs(index, value)); 
     } 
    } 

    public void Add(T item) { 
     internalList.Add(item); 
     OnListChanged(new ListChangedEventArgs(internalList.IndexOf(item), item)); 
    } 

    public void Clear() { 
     internalList.Clear(); 
     OnListCleared(new EventArgs()); 
    } 

    public bool Contains(T item) { 
     return internalList.Contains(item); 
    } 

    public void CopyTo(T[] array, int arrayIndex) { 
     internalList.CopyTo(array, arrayIndex); 
    } 

    public int Count { 
     get { return internalList.Count; } 
    } 

    public bool IsReadOnly { 
     get { return IsReadOnly; } 
    } 

    public bool Remove(T item) { 
     lock(this) { 
     int index = internalList.IndexOf(item); 
     if (internalList.Remove(item)) { 
      OnListChanged(new ListChangedEventArgs(index, item)); 
      return true; 
     } 
     else 
      return false; 
     } 
    } 

    public IEnumerator<T> GetEnumerator() { 
     return internalList.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() { 
     return ((IEnumerable) internalList).GetEnumerator(); 
    } 


    T IList<T>.this[int index] 
    { 
     get 
     { 
      throw new NotImplementedException(); 
     } 
     set 
     { 
      throw new NotImplementedException(); 
     } 
    } 

}

를 참고 - 내가 VS2010을 설계하고있다.

모든 안내가 크게 감사하겠습니다 ... 감사합니다.

답변

2

좋아, 그래서 내가 듣지 않았고 심각한 부작용없이이 작업을 할 수있는 방법이없는 것 같습니다. 난 그냥 내 코드를 거치고 System.ComponentModel.BindingList <> 확인 목록에 클래스를 기반으로 끝났다. 이것이 가능성이 있다는 것을 알았지 만 (원래 질문에 언급했듯이) 원래 코드를 작성한 사람이 아니기 때문에 기본 클래스를 변경하는 지루한 노동을 피하기를 희망했습니다. 오. =)

+0

는 바인딩 는 IList의 는 구현, 그래서 당신은 속성이나 매개 변수 유형은 IList 이다 어디 있다고는 바인딩 의 인스턴스를 사용할 수 있습니다. IList 을 구현하는 모든 클래스를 전달할 수 있습니다. 즉 인터페이스의 전체 지점입니다. –

+0

Nevermind, 데이터 소스가 IList 으로 정의 된 경우 다시 읽었을 때 BindingList의 실제 인스턴스를 사용하더라도 ListChanged 이벤트가 DGV의 처리기에 올바르게 연결될 것으로 생각하지 않습니다. –

+0

맞습니다! =) –