I have a DataGridView which I AllowUserToAddRows behavior enabled. I want to be able to force that only one row be added at time, then if the user clicks the save button the row is inserted into the database, and then another row may be added if the insert was successful.

The reason I want to do this is to get the last inserted id and insert that information into another table.

Thanks

Dani AI

Generated

Summary and practical fixes for s scenario (DataGridView in WinForms): the built-in "new row" placeholder will spawn another blank row automatically as soon as the placeholder gets focus. That is what you saw with AllowUserToAddRows = True. was on the right track about toggling the add capability; 's suggestion targets ASP.NET GridView (WebForms) and is not applicable to a WinForms DataGridView.

Two safe, maintainable approaches:

  1. Turn off automatic adding and create the single new row explicitly (recommended)
  • Set DataGridView.AllowUserToAddRows = False.
  • Provide a small "New" command (button, toolbar icon or menu) that calls BindingSource.AddNew() and puts the grid into edit mode. Save does the normal validate/EndEdit/Update cycle. This guarantees only one editable new row at a time.

Example (VB.NET):

' one-time setup
DataGridView1.AllowUserToAddRows = False

Private Sub btnNew_Click(sender As Object, e As EventArgs) Handles btnNew.Click
    BindingSource1.AddNew()
    Dim r As Integer = DataGridView1.Rows.Count - 1
    DataGridView1.CurrentCell = DataGridView1.Rows(r).Cells(0)
    DataGridView1.BeginEdit(True)
End Sub

To get the inserted identity for related inserts use a single DB round-trip (SCOPE_IDENTITY) or a transaction. Example:

Using conn As New SqlConnection(connString)
  conn.Open()
  Using cmd As New SqlCommand("INSERT INTO Parent(Name) VALUES(@n); SELECT CAST(SCOPE_IDENTITY() AS INT);", conn)
    cmd.Parameters.AddWithValue("@n", someValue)
    Dim newId As Integer = CInt(cmd.ExecuteScalar())
    ' use newId for child inserts (same connection or transaction)
  End Using
End Using

Note: prefer SCOPE_IDENTITY() over @@IDENTITY and wrap parent+child inserts in a transaction.

  1. If you must keep the placeholder visible initially: block further auto-creation when the placeholder is edited
  • In CellBeginEdit check If Rows(e.RowIndex).IsNewRow Then and temporarily disable adding (DataGridView.AllowUserToAddRows = False or BindingSource.AllowNew = False) until Save finishes and you re-enable it. This can work but can cause UI quirks (placeholder may disappear while editing), so test thoroughly.

Troubleshooting reminders

  • Call Validate() then BindingSource.EndEdit() before adapter.Update(...).
  • Use transactions for parent/child inserts so you can reliably use the returned identity.
  • If you use a DataAdapter, consider setting an InsertCommand that returns the identity and map it back to the DataRow (UpdatedRowSource / OUTPUT clause) so the DataSet receives the database-assigned key automatically.

Recommended Answers

All 3 Replies

Hi,

What you can try is to enable the add rows button until the row is added.

This is just a suggestion, bacause without code is it very difficult to answer.

Luc001, thank you for your reply. I don't have a add row button. Just a save button. On my datagridview in the properties I have the AllowUsersToAddRows behavior set to true.

So when i run my program and the datagridview is displayed it shows any existing rows plus one blank row for the user to insert new data. Which is fine.
When the user clicks into the empty row, another empty row is inserted below for the user automatically. I don't want this to happen on this particular datagridview.
What i want to happen is for the user to have to click the save button before another blank row is inserted.

Here is my save button code, but i don't think it will help much

/// <summary>
		/// The button that is clicked to update and save.
		/// </summary>
		/// <param name="sender">The Save button that received the event</param>
		/// <param name="e">event args</param>
		private void btnSave_Click(object sender, EventArgs e)
		{
			if(storeAddress.HasChanges())
			{
				adapter.Update(storeAddress);
				storeAddress.AcceptChanges();
				LoadData();
				MessageBox.Show("Changes have been saved");
			}
			else
			{
				MessageBox.Show("No changes have been saved");
			}
		}

add a webform for example : UserAddRow.aspx

in the gridview unchecked the auto-generate fields
add a hyperlinkfield

in the properties/data>>DataNavigationUrlField put the field of the table you retreive to data adapter

in the DataNavigationUrlFormatString write UserAddRow.aspx?x={0}

x contains the user ID and you can get it in page above

on page load of useraddrow.aspx do:

dim y as integer=request("x")
//now y is the ID of the user clicked
dim str as string=" here is connection string to database"
dim con as new sqlconnection=str

dim query as string=" here is your query for database"
u can use ID in your query

close your connection

response.redirect("previous page.aspx")

thats all
hope to helpfull

KOUROSH NIKZAD

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.