1

I have a DataGridView and a number of controls (for editing) all bound to a BindingSource. Everything works as expected - clicking on an entry in the DataGridView causes the bound edit controls to display and edit the selected item. What I want to be able to do is have newly created items be automatically selected in the DataGridView, with the edit controls also bound to the newly created data. To do this, I have implemented a handler for DataGridView.RowsAdded, like so:

private void dataGridViewBeasts_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
    // Force newly created items to be selected
    dataGridViewBeasts.Rows[e.RowIndex].Selected = true;
}

This works superficially, with the newly created items being selected in the DataGridView. However, the edit controls persist in referring to the item that was selected prior to creating a new item. How can I encourage them to point to the newly selected item?

  • How did you code the other event? Did you chose the clicked event or the selectionchanged event? The latter will work in the second case as well.. – TaW May 13 '16 at 14:27
  • I'm not sure which other event you mean. The new items are created by adding an item to the bound Entity Framework DbContext, if that helps at all? Thank you for your response in any case :) – Antony Little May 13 '16 at 15:13
  • You wrote: _clicking on an entry in the DataGridView causes.._ This sounds as if you have coded the Click or MouseClick event. Did you? – TaW May 13 '16 at 15:35
  • Nope. It all works via the magic of databinding and BindingSource. As far as I can tell (and this may be wrong, I'm still new to data binding with .NET) the BindingSource provides the "current record", which is bound to the selected item in the DataGridView via the DataSource property. Updating the selection updates the current record, which then applies to all controls that are bound to the same BindingSource - in this case, the edit controls. – Antony Little May 13 '16 at 15:47
  • Ah, I see. Well, in that case you will need to tell the bindingsource about it, I'd say. In the simplest case maybe something like yourBindingSource.Position = e.RowIndex ?? You do have multiselect = false, right? – TaW May 13 '16 at 17:23
  • 1
    Had followed much the same train of thought already, but to no avail. The answer below looks promising, though. I will post here when I know if it works or not. I appreciate your time and attention. – Antony Little May 13 '16 at 20:21

1 Answers1

1

Assumption:

You are adding a new row to the underlying DataSource, not directly to the DataGridView.

Result:

The problem you are encountering here is that the binding on all of your editing controls are tied to the DataGridView.CurrentRow bound item - which is a get only property and is indicated by an arrow in the row header column.

Changing the CurrentRow is discussed in Selecting a row in a DataGridView and having the arrow on the row header follow.

So it should be as simple as setting the CurrentCell to Cell[0] of the newly added row. Except...

Setting CurrentCell in the DataGridView.RowsAdded event will fail. Conceptually, it works - the new row becomes the CurrentRow. But after that event is finished, debugging will show that the CurrentRow is immediately reset to its prior value. Instead, set the CurrentCell after your code to add the new row. For example when BindingSource.DataSource:

Is a DataTable:

DataTable dt = theBindingSource.DataSource as DataTable;
dt.Rows.Add("New Row", "9000");

dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[0];

Or a List<Example>:

List<Example> list = theBindingSource.DataSource as List<Example>;
list.Add(new Example() { Foo = "New Row", Bar = "9000" });

// Reset the bindings.
dataGridView1.DataSource = null;
dataGridView1.DataSource = theBindingSource;

dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[0];
Community
  • 1
  • 1
OhBeWise
  • 5,350
  • 3
  • 32
  • 60