2011-03-24 95 views
2

我有一個非常簡單的類:人物:C#更新DataGridView的基礎上的IList

class People 
{ 
    private string LastName = null; 
    private string FirstName = null; 
    private string Status = null; 

    public string lastName 
    { 
    get { return LastName; } 
    set { LastName = value; } 
    } 

    public string firstName 
    { 
    get { return FirstName; } 
    set { FirstName = value; } 
    } 

    public string status 
    { 
    get { return Status; } 
    set { Status = value; } 
    } 

    public People(string lastName, string firstName, string status) 
    { 
    LastName = lastName; 
    FirstName = firstName; 
    Status = status; 
    } 
} 

而且,我有一個實現該接口的IList <>,其目的是要作爲的集合另一個類People class,名爲PeopleList <>。 PeopleList <>是特別的,因爲我直接將此類的實例綁定到DataGridView。通常,我絕不會使用IList <>作爲datagridview(DGV)的數據源,原因有一個:IList不會生成ListChanged事件,這意味着一旦將DGV綁定到IList,行數就會減少在DGV中設置。換句話說,如果新項目被添加到IList <>,DGV將不會顯示它們!要實現這一目標的唯一方法是將DGV的數據源設置爲空,然後在更改完成後將其重新綁定到IList <>。

一個的BindingList是更適合於這種類型的需要,但很可惜,原因我不能進入,當務之急是我用一個IList <>作爲接口。爲了解決這個問題,我找到了一些代碼,可以將ListChanged事件集成到IList接口的實現中,但我遇到了一些麻煩。這似乎即使這個代碼,我將不得不有一個事件處理程序的方法嗎?在某些時候,我將不得不聲明這個方法作爲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

BindingList 實現IList ,因此您可以在任何位置使用BindingList 的實例,該屬性或參數的類型爲IList 。你可以通過任何實現IList 的類,這就是接口的全部要點。 – 2011-04-01 03:29:26

+0

沒關係,我重新閱讀並意識到如果您的數據源被定義爲IList ,那麼即使您使用的是BindingList的實際實例,我也不認爲它的ListChanged事件將正確連線到您的DGV上的處理程序。 – 2011-04-01 03:38:20

+0

這是正確的! =) – 2011-04-01 22:20:11