我有一个ListBox,其DataSource是一个BindingSource。 BindingSource的DataSource是我编写的实现IList< T>的自定义类。当用户为列表中的新项输入数据时,我通过使用新项调用BindingSource.Insert()来更新BindingSource。这会将项添加到ListBox,但它似乎不会修改作为BindingSource的DataSource的基础列表。
当我尝试用普通的List< T>做同样的事情时而不是我的自定义IList类(FilteredList< T>),该列表由BindingSource更新。所以问题似乎在于我的自定义类。但是我在FilteredList< T>中的每个方法上都加了断点,除了构造函数之外,它们都没有被调用。所以我很难过。
这里,作为参考,是FilteredList< T>的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AmesView.Encapsulation
{
public class FilteredList<T>: IList<T>
{
public delegate bool TestMethod<T>(T item);
private IList<T> _innerList;
private TestMethod<T> _test;
public FilteredList(IList<T> innerList, TestMethod<T> test)
{
if (innerList == null)
{
throw new ArgumentException("innerList must not be null");
}
if (test == null)
{
throw new ArgumentException("test must not be null");
}
_innerList = innerList;
_test = test;
}
public int IndexOf(T item)
{
int count = 0;
foreach (T tmp in _innerList)
{
if (_test(tmp))
{
if (item.Equals(tmp))
{
break;
}
count++;
}
}
return count;
}
public void Insert(int index, T item)
{
int count = 0;
int allidx = 0;
foreach (T tmp in _innerList)
{
if (_test(tmp))
{
if (count == index)
{
_innerList.Insert(allidx, item);
return;
}
count++;
}
allidx++;
}
}
public void RemoveAt(int index)
{
int count = 0;
int allidx = 0;
foreach (T tmp in _innerList)
{
if (_test(tmp))
{
if (count == index)
{
_innerList.RemoveAt(allidx);
return;
}
count++;
}
allidx++;
}
}
public T this[int index]
{
get
{
int count = 0;
int allidx = 0;
foreach (T tmp in _innerList)
{
if (_test(tmp))
{
if (count == index)
{
return _innerList[allidx];
}
count++;
}
allidx++;
}
return default(T);
}
set
{
int count = 0;
int allidx = 0;
foreach (T tmp in _innerList)
{
if (_test(tmp))
{
if (count == index)
{
_innerList[allidx] = value;
}
count++;
}
allidx++;
}
}
}
public void Add(T item)
{
_innerList.Add(item);
}
public void Clear()
{
_innerList.Clear();
}
public bool Contains(T item)
{
foreach (T tmp in _innerList)
{
if (tmp.Equals(item) && _test(tmp))
{
return true;
}
}
return false;
}
public void CopyTo(T[] array, int arrayIndex)
{
int count = 0;
foreach (T tmp in _innerList)
{
if (_test(tmp))
{
int idx = arrayIndex + count;
if (idx < array.Length)
{
array[idx] = tmp;
}
count++;
}
}
}
public int Count
{
get
{
int count = 0;
foreach (T tmp in _innerList)
{
if (_test(tmp))
{
count++;
}
}
return count;
}
}
public bool IsReadOnly
{
get
{
return _innerList.IsReadOnly;
}
}
public bool Remove(T item)
{
return _innerList.Remove(item);
}
public IEnumerator<T> GetEnumerator()
{
foreach (T tmp in _innerList)
{
if (_test(tmp))
{
yield return tmp;
}
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
foreach (T tmp in _innerList)
{
if (_test(tmp))
{
yield return tmp;
}
}
}
}
}
答案 0 :(得分:0)
这似乎是BindingSource类的预期行为。请参阅Microsoft关于BindingSource.DataSource属性的文档中的“备注”部分:
由于DataSource可以设置为许多不同类型的对象,因此许多类型都有自定义行为。 List&lt; T&gt;类型的DataSource的行为显然是要包装List&lt; T&gt;在BindingList&lt; T&gt;中,而实现IEnumerable&lt; T&gt;的其他类的行为。是创建一个新的BindingList&lt; T&gt;来自IEnumerable&lt; T&gt;的项目。被复制。因为我的FilteredList&lt; T&gt; class没有从List&lt; T&gt;继承,它得到了“不太特殊的处理”,并被作为通用IEnumerable&lt; T&gt;处理。而不是List&lt; T&gt;。不幸的是,出于我的目的,但可以理解。
由于得出这个结论,我偶然发现了另一个有用的信息:如果你创建一个BindingList&lt; T&gt;你自己,传递一个IList&lt; T&gt;到构造函数,然后分配这个BindingList&lt; T&gt;对于BindingSource的DataSource属性,一切正常,对BindingSource所做的更改都会反映在原始列表中。