2011-03-24 84 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