InvalidOperationException with DataGridView bound to object data source

B

bort

I am getting an InvalidOperationException with the message "Operation
is not valid due to the current state of the object." when using the
DataGridView and an object data source in 2.0. After going crazy
trying to find the source in a larger application I created a very
simple app to see if I could reproduce the error and found that even a
simple example application causes it.

Here are the steps that reproduce it:

1) Create a new project with a single form with only a DataGridView in
it.
2) Create a simple object with two properties. For example:
public class Widget
{
private string _name;
private int _quantity;
public Widget()
{
_name = "";
_quantity = 0;
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public int Quantity
{
get { return _quantity; }
set { _quantity = value; }
}
}
3) Compile the project so the data source wizard can find the Widget
class
4) Create an object data source for the Widget class (Data Menu > Add
New Data Source > Select "Object" > Navigate to the Widget class)
5) Select this data source for the grid (DataGridView properties >
DataSource > Other Data Sources > Project Data Sources > Widget)

Start up the project and everything looks fine. You can add, edit, and
delete Widget rows.

Now try this:
6) Delete all rows out of the grid
7) In the first cell type something to start a new row
8) Tab over to the next field
9) Push esc to cancel editing the row
10) InvalidOperationException is thrown with the message "Operation is
not valid due to the current state of the object."

This is the only scenario that causes this to happen. In any other row
this would simply cause the row to be removed since it is new. The
exception is only thrown when canceling the edit of a new first row,
only after you edit one of the cells, and only if you are not currently
editing another cell.

When I originally ran into this problem I was binding the grid to a
class inherited from BindingList<Widget> and the same exception was
being thrown. Since I had overwritten some of the methods in the
BindingList class I found that after pushing escape the following
happens in the BindingList class:
1) RemoveItem is called. <- Ok, we are canceling a new item so the
current item needs to be removed from the collection.
2) AddNewCore is called <- This makes sense, since the user is on the
first row the previous row can't be selected so we need to start a new
one.
3) AddNewCore is called AGAIN <- This is where the exception occurs and
I don't understand why it's adding two new core objects to the
collection. The exception is thrown from the
DataGridView.DataGridViewDataConnection.ProcessListChanged method.
From what I've found this method throws this exception if the
ListChanged event is fired from the data source multiple times when the
grid only expects it to be fired once.

Is there something I am missing or is this a bug in the framework? If
it's the latter how do I work around it?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top