我有一个非常简单的类(class):People:
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;
}
}
而且,我还有另一个实现接口(interface) IList<> 的类,该类旨在用作 People 类的集合,称为 PeopleList<>。 PeopleList<> 很特别,因为我直接将此类的实例绑定(bind)到 DataGridView。通常情况下,我永远不会使用 IList<> 作为 datagridview (DGV) 的数据源,原因有一个:IList 不会生成 ListChanged 事件,这意味着一旦将 DGV 绑定(bind)到 IList<> 行数在 DGV 中设置。换句话说,如果将新项目添加到 IList<>,DGV 将不会显示它们!使其发挥作用的唯一方法是将 DGV 的数据源设置为 null,然后在更改后将其重新绑定(bind)到 IList<>。
BindingList 更适合这种类型的需求,但可惜的是,由于我无法详细说明的原因,我必须使用 IList<> 作为接口(interface)。为了解决这个问题,我找到了一些代码,据称这些代码将 ListChanged 事件集成到 IList<> 接口(interface)的实现中,但我遇到了一些麻烦。似乎即使有了这段代码,我也必须有一个事件处理程序方法,对吗?在某些时候我必须将此方法声明为 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 中进行设计。
任何指导将不胜感激...谢谢!
最佳答案
好吧,所以我没有收到回复,而且似乎没有一种方法可以在没有严重副作用的情况下完成这项工作。我最终只是删除了我的代码并将我的列表类基于 System.ComponentModel.BindingList<> ,这似乎工作正常。我知道这是一种可能性(正如我在问题中提到的),但希望避免更改基类的繁琐工作,因为我不是编写原始代码的人。噢,井。 =)
关于data-binding - c# 基于IList更新Datagridview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5421806/