views:

41

answers:

2

Hello everybody,

I am new to c# and try to bind a datagridview to a mssql database in visual studio 2010. The databindings are OK and everything seems to work. Except for a few strange errors:

I get the error in the subject after: updating the same row 2 times, deleting a new inserted row, after updating a row when an other row was deleted (word changes to DeleteCommand)

None of the solutions I found on Google workes for me. I hope someone can help me with this. Here is te code:

    private void fillDatagrid()
        {
            //fill datagrid ADO.NET
            conn = new SqlConnection(TestApp.Properties.Settings.Default.TestdatabaseConnectionString);
            cmd = conn.CreateCommand();
            conn.Open();
            cmd.CommandText = "SelectFrom";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@table", SqlDbType.NVarChar, 50).Value = "Countries";
            cmd.Parameters.Add("@filters", SqlDbType.NVarChar, 300).Value = "";

            adapt = new SqlDataAdapter(cmd);
            dt = new DataTable();
            adapt.Fill(dt);
            dt.TableName = "Countries";

            conn.Close();

            BindingSource src = new BindingSource();
            src.DataSource = dt;
            dt.RowChanged += new DataRowChangeEventHandler(dt_RowChanged);

            dgDatabaseGrid.DataSource = src;
            dgDatabaseGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
            //dgDatabaseGrid.RowValidating += new DataGridViewCellCancelEventHandler(dgDatabaseGrid_RowValidating);

            //disable columns:
            dgDatabaseGrid.Columns[0].Visible = false;
            dgDatabaseGrid.Columns["date_insert"].Visible = false;
            dgDatabaseGrid.Columns["user_insert"].Visible = false;
            dgDatabaseGrid.Columns["date_change"].Visible = false;
            dgDatabaseGrid.Columns["user_change"].Visible = false;
            dgDatabaseGrid.Columns["deleted"].Visible = false;

            //auto size last column
            dgDatabaseGrid.Columns["remarks"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;


            SqlCommandBuilder cb = new SqlCommandBuilder(adapt);
        }

        void dt_RowChanged(object sender, DataRowChangeEventArgs e)
        {
            try
            {
                adapt.Update(dt);
            }
            catch (SqlException ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

private void dgDatabaseGrid_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            if (!e.Row.IsNewRow)
            {


                DialogResult response = MessageBox.Show("Are you sure?", "Delete row?",
                                     MessageBoxButtons.YesNo,
                                     MessageBoxIcon.Question,
                                     MessageBoxDefaultButton.Button2);

                if (response == DialogResult.Yes)
                {

                    //ipv delete --> deleted=1
                    conn.Open();
                    cmd = conn.CreateCommand();
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandText = "DeleteFrom";
                    cmd.Parameters.Add("@table", SqlDbType.NVarChar, 50).Value = "Countries";
                    cmd.Parameters.Add("@id", SqlDbType.Int).Value = e.Row.Cells[0].Value;
                    cmd.ExecuteNonQuery();
                    conn.Close();


                    //delete from datagrid:
                    dt.Rows[dgDatabaseGrid.SelectedCells[0].RowIndex].Delete();

                }

                //always cancel!
                e.Cancel = true;

            }
        }
A: 

after updating the same row 2 times

Is there a Timestamp column (or any other column that is changed/filled on the Db server) ?

Your problem could happen when the in-memory row is different from what's in the Db. And because you use a SP for the SelectCmd there (probably) is no refresh after an update.

after deleting a new inserted row

Similar, caused not fetching the new Id after an insert

after updating a row when an other row was deleted (word changes to DeleteCommand)

totally unclear.
But why do you Delete rows 'manually' instead of leaving it to the adapt.Update() ? And are you sure that not both methods are executed?

Henk Holterman
A: 

There are no Timestamp columns. But there is a trigger on update that changes 2 columns (user_change and time_change). So probably that's the problem.

Is there a way to synchronize data without reloading the whole dataset? The problem is that the sort order and column width are set to default while re-loading the whole set.

The delete command is overwritten because no data may be lost. It must be possible for the users to delete the data, but the system admin has to be able to restore the data without a backup. So there is a 'deleted' column in each table, which is just a BIT field (0 or 1).

In the delete SP the bit is set to 1, in de select SP only the rows with deleted=0 are fetched.

Thanks for the step ahead!!! :)

VeeWee
I just added these properties to the commandBuilder:cb.SetAllValues = false;cb.ConflictOption = ConflictOption.OverwriteChanges;Now the update and delete of a row is fixed. Only the new rows cannot be updated/deleted. I notice, the PK is empty in the recordset.
VeeWee
VeeWee: Next time, use a comment with @Henk, and/or edit your question. O sorry, you can't comment yet.
Henk Holterman
I'm not able to help you further but I suggest a new Question: How to refresh record after an update with a SP
Henk Holterman
ok, Thank you for the help!
VeeWee