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?
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];