情景:
基本上我有一个
System.Windows.Forms.DataGridView
继承BindingSource和IBindingList
具有2个标准列表作为私有属性的类
DataGridView dgv = new ...
MyBindingSource bindingSource = new ...
MyList list = new ...
DataGridView.DataSource属性设置为BindingSource,BindingSource.DataSource设置为列表的私有列表之一
bindingSource.DataSource = list.ListA;
dgv.DataSource = bindingSource;
我从数据库中获取了大量信息,我将信息转换为对象并一次将其添加到MyList中,最后应该显示在DataGridView中。
我希望所有这些都有意义,现在问题是: 将单个对象添加到列表(而不是bindingsource)后,我希望项目显示在DataGridView中。但是我目前唯一可以使用的方法是构造另一个bindingSource实例,并附加1个新对象,并将DataGridView.DataSource设置为新的bindingSource。这个过程非常低效,datagridview每次都要使整个事情无效,这很狡猾。
相反,我希望List通知BindingSource告诉DataGridView一个新对象已被添加,所以它可以做到这一点。我试过这个,但我一直得到一个IndexOutOfrange异常,说'索引-1处的项目没有值'。 我查看了BindingSource,实际上位置是-1,Current属性抛出相同的异常。每次位置和当前属性都正确时,我创建新的BindingSource。
那么当我将一个项目添加到列表中时,为了让这些属性更新,我需要做些什么?我用反射器打开它,看看它在哪里设置,看起来像“CurrencyManager”与它有关。我尝试了一些像base.OnDataMemberChanged base.OnListChanged这样的东西无济于事。
编辑:忘了提到我只是在我点击数据网格视图中的一行时才得到异常,它会正确添加项目。所以它就像DataGridView与BindingSource
不同步答案 0 :(得分:2)
当DataSource更改其内容时,DataGridView会清除其网格并引发SelectionChanged事件以及与用户交互相关的其他事件。很重要的是,当事件被引发时,根本没有数据显示,所以如果你有一个SelectionChanged事件监听器并且它正在访问内部的行或列,它将在访问行时引发超出范围的异常。解决方案:在使用任何数据网格资源之前,始终将Rows.count检查为0值。干杯
答案 1 :(得分:1)
您是否考虑过使用ObservableCollection?每当从集合中添加或删除项目时,它将不会更新与其绑定的控件。它也会对集合中的项目属性执行相同的操作(尽管您必须手动引发事件)
我不确定导致异常的原因
答案 2 :(得分:1)
如果您使用BindingList(通用),它将通知项目添加/删除和单个项目更改。 (http://msdn.microsoft.com/en-us/library/ms132679.aspx)