views:

785

answers:

3

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

DataGridView dgv = new ...

MyBindingSource bindingSource = new ...

MyList list = new ...

The DataGridView.DataSource property gets set to the BindingSource and the BindingSource.DataSource is set to one of the list's private List

bindingSource.DataSource = list.ListA;

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.

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.

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.

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.

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

+1  A: 

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 )

I'm not to sure what could be causing the exception

roo
+1  A: 

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)

Hans Løken
This is what I do too :) +1
leppie
+1  A: 

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

Sebastian