Data binding c#基于IList更新Datagridview
我有一个非常简单的课程:人:Data binding c#基于IList更新Datagridview,data-binding,c#-4.0,datagridview,ilist,Data Binding,C# 4.0,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 firs
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的类,它被用作PeopleList类的集合。PeopleList很特别,因为我直接将这个类的一个实例绑定到DataGridView。通常,我不会将IList用作datagridview(DGV)的数据源,原因很重要:IList不会生成ListChanged事件,这意味着一旦将DGV绑定到IList,就会设置DGV中的行数。换句话说,如果新项目添加到IList,DGV将不会显示它们!使其工作的唯一方法是将DGV的数据源设置为null,然后在进行更改后将其重新绑定到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();
}
}
类人物列表:IList
{
私人名单;
公共类ListChangedEventArgs:EventArgs{
公共整数指数;
公共交通项目;
public ListChangedEventArgs(整数索引,T项){
这个指数=指数;
this.item=项目;
}
}
公共委托无效ListChangedEventHandler(对象源,ListChangedEventArgs e);
公共委托无效列表ClearedEventHandler(对象源,事件参数e);
公共事件列表更改事件处理程序列表更改;
公共事件列表ClearedEventHandler列表已清除;
公众人物名单(){
internalList=新列表();
}
公众人物列表(IList列表){
内部列表=列表;
}
公共人物列表(IEnumerable集合){
internalList=新列表(集合);
}
受保护的虚拟void OnListChanged(ListChangedEventArgs e){
如果(ListChanged!=null)
列表更改(本,e);
}
受保护的虚拟void OnListCleared(事件参数e){
如果(ListCleared!=null)
(本,e);
}
公共整数索引(T项){
返回internalList.IndexOf(项目);
}
公共空白插入(整数索引,T项){
内部列表。插入(索引,项目);
OnListChanged(新的ListChangedEventArgs(索引,项));
}
公共无效删除(整数索引){
T项=内部列表[索引];
内部列表。删除(项目);
OnListChanged(新的ListChangedEventArgs(索引,项));
}
T这个[int索引]{
获取{return internalList[index];}
设置{
内部列表[索引]=值;
OnListChanged(新的ListChangedEventArgs(索引,值));
}
}
公共作废新增(T项){
内部列表。添加(项目);
OnListChanged(新的ListChangedEventArgs(internalList.IndexOf(item),item));
}
公共空间清除(){
internalList.Clear();
OnListCleared(新事件参数());
}
公共布尔包含(T项){
返回内部列表。包含(项);
}
public void CopyTo(T[]数组,int arrayIndex){
CopyTo(数组,arrayIndex);
}
公共整数计数{
获取{return internalList.Count;}
}
公共图书馆是只读的{
获取{return IsReadOnly;}
}
公共布尔删除(T项){
锁(这个){
int index=internalList.IndexOf(项目);
如果(内部列表。删除(项目)){
OnListChanged(新的ListChangedEventArgs(索引,项));
返回true;
}
其他的
返回false;
}
}
公共IEnumerator GetEnumerator(){
返回internalList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator(){
return((IEnumerable)internalList).GetEnumerator();
}
T IList.此[int索引]
{
得到
{
抛出新的NotImplementedException();
}
设置
{
抛出新的NotImplementedException();
}
}
}
仅供参考-我正在VS2010中设计
任何指导都将不胜感激。。。谢谢 好的,所以我没有听到回音,而且似乎没有一种方法可以使这项工作没有严重的副作用。我最终只是删除了我的代码,并将我的list类建立在System.ComponentModel.BindingList上,它似乎工作正常。我知道这是一种可能性(正如我在问题中提到的),但我希望避免修改基类的繁琐工作,因为我不是编写原始代码的人。哦,威尔斯 BindingList实现了IList,因此您可以在属性或参数类型为IList的任何位置使用BindingList实例。您可以传入任何实现IList的类,这是接口的全部要点。不过,如果您的数据源定义为IList,我会重新读取并实现,那么即使您使用的是BindingList的实际实例,我认为它的ListChanged事件不会正确地连接到DGV上的处理程序。在执行此操作时,您可能应该使用
IBindingList
,而不是从BindingList
继承的类,这样,如果需求再次发生变化,您后面的任何人都不必再次执行;)