我有一個非常簡單的類:人物: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設計。
任何指導將不勝感激...謝謝!
BindingList實現IList ,因此您可以在任何位置使用BindingList 的實例,該屬性或參數的類型爲IList 。你可以通過任何實現IList 的類,這就是接口的全部要點。 –
2011-04-01 03:29:26
沒關係,我重新閱讀並意識到如果您的數據源被定義爲IList,那麼即使您使用的是BindingList的實際實例,我也不認爲它的ListChanged事件將正確連線到您的DGV上的處理程序。 –
2011-04-01 03:38:20
這是正確的! =) – 2011-04-01 22:20:11