Windows DataGridView BindingSource 索引超出范围异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2331022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Windows DataGridView BindingSource Index out of range exception
提问by Daniel
Scenario:
设想:
Basically i have a
基本上我有一个
System.Windows.Forms.DataGridView
A class that inherits BindingSource and IBindingList
A class that has 2 standard List as private properties
System.Windows.Forms.DataGridView
一个继承 BindingSource 和 IBindingList 的类
具有 2 个标准 List 作为私有属性的类
DataGridView dgv = new ...
DataGridView dgv = 新 ...
MyBindingSource bindingSource = new ...
MyBindingSource bindingSource = 新 ...
MyList list = new ...
MyList 列表 = 新 ...
The DataGridView.DataSource property gets set to the BindingSource and the BindingSource.DataSource is set to one of the list's private List
DataGridView.DataSource 属性设置为 BindingSource 并且 BindingSource.DataSource 设置为列表的私有列表之一
bindingSource.DataSource = list.ListA;
bindingSource.DataSource = list.ListA;
dgv.DataSource = bindingSource;
dgv.DataSource = bindingSource;
I am getting a bunch of information streaming in from a database, and i convert the information to objects and add it to the MyList one at a time and in the end should be shown in the DataGridView.
我从数据库中获取了一堆信息,我将这些信息转换为对象并将其一次添加到 MyList 中,最后应该显示在 DataGridView 中。
I hope all that made sense, now the problem: After adding a single object to the list (not the bindingsource) i want the item to be displayed in the DataGridView. But the only way i can currently get that to work is to construct another instance of a bindingSource with the 1 new object appended and set the DataGridView.DataSource to the new bindingSource. This ofcourse is horribly inefficient and the datagridview has to invalidate the whole thing every time, which is dodgy.
我希望这一切都有意义,现在的问题是:将单个对象添加到列表(而不是绑定源)后,我希望该项目显示在 DataGridView 中。但我目前可以让它工作的唯一方法是构造一个 bindingSource 的另一个实例,并附加 1 个新对象,并将 DataGridView.DataSource 设置为新的 bindingSource。这当然是非常低效的,并且 datagridview 每次都必须使整个事情无效,这很狡猾。
Instead i want the List to notifiy the BindingSource which tells the DataGridView a new object has been added so it can do it's thing. I tried this but i kept getting a IndexOutOfrange exception saying 'Item at index -1 does not have a value'. I had a look at the BindingSource and indeed the position was -1 and the Current property threw that same exception. When i create the new BindingSource every time the position and Current properties are correct.
相反,我希望 List 通知 BindingSource,它告诉 DataGridView 一个新对象已添加,因此它可以完成它的工作。我试过了,但我一直收到一个 IndexOutOfrange 异常,说“索引 -1 处的项目没有值”。我查看了 BindingSource,确实位置是 -1,而 Current 属性抛出了同样的异常。当我每次位置和当前属性正确时创建新的 BindingSource 时。
So what do i have to do in order for those properties to get updated when i add a item to the list? I opened it up with reflector to see where it was being set and looked like "CurrencyManager" had something to do with it. I tried a few things like base.OnDataMemberChanged base.OnListChanged to no avail.
那么当我将一个项目添加到列表中时,我必须做什么才能使这些属性得到更新?我用反射器打开它以查看它的设置位置,看起来“CurrencyManager”与它有关。我尝试了一些诸如 base.OnDataMemberChanged base.OnListChanged 之类的东西,但无济于事。
Edit: Forgot to mention i only get the exception when i click on a row in the datagrid view, it adds the items fine. So it's like the DataGridView is out of sync with the BindingSource
编辑:忘了提到我只在我点击数据网格视图中的一行时才会得到异常,它会很好地添加项目。所以就像 DataGridView 与 BindingSource 不同步
回答by Sebastian
When DataSource is changing its content, DataGridView clears its grid and raises SelectionChanged event and other events witch are connected with user interaction. It is iportant to know that when the event is raised there is no data at all to be displayed, so if u got a SelectionChanged event listener and it is accessing rows or columns inside, it will raise out of bound exception when accessing rows. Solution: always check Rows.count against 0 value before use any datagrid resources. Cheers
当 DataSource 改变其内容时,DataGridView 清除其网格并引发 SelectionChanged 事件和其他与用户交互相关的事件。重要的是要知道,当引发事件时根本没有数据要显示,所以如果你有一个 SelectionChanged 事件侦听器并且它正在访问里面的行或列,它会在访问行时引发越界异常。解决方案:在使用任何数据网格资源之前,始终检查 Rows.count 是否为 0 值。干杯
回答by roo
Have you considered using an ObservableCollection? Whenever there are items added or removed from the collection it will notifiy the control its bound to that is has been updated. It will also do the same with properties of items in the collection as well ( although you have to raise the event manually )
您是否考虑过使用ObservableCollection?每当从集合中添加或删除项目时,它都会通知控件其绑定到的控件已更新。它也会对集合中项目的属性执行相同的操作(尽管您必须手动引发事件)
I'm not to sure what could be causing the exception
我不确定是什么导致了异常
回答by Hans L?ken
If you use a BindingList(generic) instead it will notify of item adds/deletes and individual item changes as well. (http://msdn.microsoft.com/en-us/library/ms132679.aspx)
如果您使用 BindingList(generic) 代替,它将通知项目添加/删除和单个项目更改。( http://msdn.microsoft.com/en-us/library/ms132679.aspx)