Adding new row in DataGridView doesn't add to BindingList<T>

2.4k Views Asked by At

I've a little problem using a DataGridView with AllowUserToAddRows set to True that is binding to a list (BindingList<State>).

When adding a new row through the GUI, the row isn't added to the BindingList.

I've a entity which contains a collection with other entities. For example: Country contains States. So, the new row in datagridview isn't added in the StateCollection on country object.

That's is how I add the BindingList to the DataGridView:

var bl = new BindingList<State>(country.StatesCollection.ToList<State>());
grdData.DataSource = bl;

Properties:

EditMode is set to EditOnKeystrokeOrF2

If more data is needed, please ask me.

1

There are 1 best solutions below

2
On BEST ANSWER

Following your code, I initialized context.MyEntities with 3 MyEntity objects.

After binding, the DataGridView shows the 3 rows as well as the expected * NewRow. Thus:

context.MyEntities.Length == 3 // .Count or .Length depending on data structure
((BindingList<MyEntity>)grdData.DataSource).Count == 3
grdData.Rows.Count == 4

After entering data into the NewRow within the GUI, the DataGridView now shows 4 rows as well as the expected * NewRow. Thus:

context.MyEntities.Length == 3
((BindingList<MyEntity>)grdData.DataSource).Count == 4
grdData.Rows.Count == 5

Adding an item to the DataGridView did indeed add the object to the BindingList source, but not to the actual context.MyEntities source, which I assume is where you are expecting to see this new item added.

The reason you are seeing this behavior is because of this line:

var bl = new BindingList<MyEntity>(context.MyEntities.ToList<MyEntity>());

You are declaring a new object for your binding. Even if context.MyEntities is also a BindingList<MyEntity> (I doubt since that would negate the reason for the above line of code), it will not be updated with the new entry. For the desired behavior, you have two options:

  1. Change context.MyEntities type to BindingList<MyEntity>, then simply change your binding to:

    grdData.DataSource = context.MyEntities;
    
  2. Handle DataGridView.RowsAdded and manually update context.MyEntities by a) adding the new item or b) refreshing the original object:

    private void grdData_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
    {
        var source = ((BindingList<MyEntity>)grdData.DataSource);
        context.MyEntities = // source converted to the correct Enumerable type
    }