Click here to Skip to main content
15,891,184 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
i have three events in cellcontentclick and cellenter and cellleave events of datagridview..winforms...
iam trying to write code this is done :when my checkbox is clicked it allows us to enter data in othercolumn.when i uncheck it it disables us to enter data in other column. 
ths is what i have to do :
when checkbox cell is clicked the cursor has to go to the particular cell automatically.
and must allow us to write data in it..while leaving the cell using cellleave event i have to check whether is empty or not.if empty that checkbox must be uncheked that means have to make it false.and must not allow any user to enter data in other column.else if cell while leaving is not empty it has to store the data of that row in database


What I have tried:

 private void button1_Click(object sender, EventArgs e)
        {

            
            int row = 0;
            dataGridView1.Rows.Add();
            row = dataGridView1.Rows.Count - 1;
            dataGridView1["AMENITIESNAME", row].Value = textBox1.Text;
            dataGridView1["DESCRIPTION", row].Value = textBox2.Text;

            dataGridView1["CHECKBOX", row].Value = false;
            dataGridView1["AMOUNT", row].ReadOnly = true;
            LoadSerial();
        }

        private async void dataGridView1_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
        {

            if (lastCell != null)
            {
                var lastAmtCell = dataGridView1.Rows[lastCell.RowIndex].Cells["AMOUNT"];
                if (lastAmtCell.ReadOnly == true)
                {
                    // MessageBox.Show("working");

                    lastCell.Value = false;
                }
                else
                {
                    // MessageBox.Show("working");

                    lastCell.Value = true;
                }
            }
            //  System.Threading.Thread.Sleep(300);
            // Stopwatch stopwatch = Stopwatch.StartNew();
            // Thread.SpinWait(1000000);
            // await Task.Delay(20000);
   

            var amountCell = dataGridView1.Rows[e.RowIndex].Cells["AMOUNT"];
            if (e.RowIndex > -1 && dataGridView1.CurrentCell == dataGridView1.Rows[e.RowIndex].Cells["CHECKBOX"])
            {

                if (amountCell.ReadOnly == true)

                {
                    amountCell.ReadOnly = false;
                    amountCell.Style.BackColor = Color.White;

                }



                else
                {
                    dataGridView1.Rows[e.RowIndex].Cells["AMOUNT"].ReadOnly = true;
                    amountCell.Style.BackColor = Color.Gray;

                    //dataGridView1.Columns["AMOUNT"].Visible = true;

                }
                lastCell = dataGridView1.CurrentCell;
            }
        }


        private void dataGridView1_CellValidating_1(object sender, DataGridViewCellValidatingEventArgs e)
        {


           /* foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                //dataGridView1.Rows[e.RowIndex].Cells["CHECKBOX"].Value=true;
                //dataGridView1.Rows[e.RowIndex].Cells["CHECKBOX"].Value = true;

                DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell)row.Cells[3];
                if (chk.Value.ToString().ToLower() == " false")
                {
                    //dataGridView1.CurrentCell = dataGridView1[0, 2];
                    if (Convert.ToString(row.Cells["AMOUNT"].Value) != string.Empty)
                    {
                        SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-T09HLQF;Initial Catalog=BANQUET HALL ;PASSWORD=Secret;Integrated Security=True;");
                        con.Open();
                        for (int i = 0; i < dataGridView1.Rows.Count; i++)
                        {
                            //string StrQuery = @"INSERT INTO AMENITIES VALUES (" + dataGridView1.Rows[i].Cells[0].Value + ", " + dataGridView1.Rows[i].Cells[1].Value + "," + dataGridView1.Rows[i].Cells[2].Value + "," + dataGridView1.Rows[i].Cells[3].Value + "," + dataGridView1.Rows[i].Cells[4].Value + ");";

                            string StrQuery = @"INSERT INTO AMENITIES(ID,AMENITIESNAME,DESCRIPTION,CHECKBOX,AMOUNT) VALUES (@ID,@AMENITIESNAME,@DESCRIPTION,@CHECKBOX,@AMOUNT)";
                            SqlCommand CMD = new SqlCommand(StrQuery, con);
                            CMD.Parameters.AddWithValue("@ID", dataGridView1.Rows[i].Cells[0].Value);
                            CMD.Parameters.AddWithValue("@AMENITIESNAME", dataGridView1.Rows[i].Cells[1].Value);
                            CMD.Parameters.AddWithValue("@DESCRIPTION", dataGridView1.Rows[i].Cells[2].Value);
                            CMD.Parameters.AddWithValue("@CHECKBOX", dataGridView1.Rows[i].Cells[3].Value);
                            CMD.Parameters.AddWithValue("@AMOUNT", dataGridView1.Rows[i].Cells[4].Value);

                            CMD.ExecuteNonQuery();



                            // dataGridView1.Rows[lastCell.RowIndex].Cells["AMOUNT"].ReadOnly = true;
                        }
                        chk.Value = "false";
                        //dataGridView1.Rows[lastCell.RowIndex].Cells["AMOUNT"].ReadOnly = true;
                    }

                    else
                    {
                        MessageBox.Show("please provide amount"); return;
                        //   dataGridView1.Rows[e.RowIndex].Cells["CHECKBOX"].Value = false;
                    }
                }

            }*/

        }

        private void dataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
        {


        }

        private void dataGridView1_CellMouseLeave(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 4)
            {

                foreach (DataGridViewRow row in dataGridView1.Rows)
                {

                    if (Convert.ToString(row.Cells["AMOUNT"].Value) == string.Empty) 
                    {
                        MessageBox.Show("Please enter  value");
                        dataGridView1.Rows[e.RowIndex].Cells["CHECKBOX"].Value = false;
                        dataGridView1.Rows[e.RowIndex].Cells[4].Value = null;
                        return;


                    }
                    else
                    {
                        SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-T09HLQF;Initial Catalog=BANQUET HALL ;PASSWORD=Secret;Integrated Security=True;");
                        con.Open();
                        for (int i = 0; i < dataGridView1.Rows.Count; i++)
                        {
                            //string StrQuery = @"INSERT INTO AMENITIES VALUES (" + dataGridView1.Rows[i].Cells[0].Value + ", " + dataGridView1.Rows[i].Cells[1].Value + "," + dataGridView1.Rows[i].Cells[2].Value + "," + dataGridView1.Rows[i].Cells[3].Value + "," + dataGridView1.Rows[i].Cells[4].Value + ");";

                            string StrQuery = @"INSERT INTO AMENITIES(ID,AMENITIESNAME,DESCRIPTION,CHECKBOX,AMOUNT) VALUES (@ID,@AMENITIESNAME,@DESCRIPTION,@CHECKBOX,@AMOUNT)";
                            SqlCommand CMD = new SqlCommand(StrQuery, con);
                            CMD.Parameters.AddWithValue("@ID", dataGridView1.Rows[i].Cells[0].Value);
                            CMD.Parameters.AddWithValue("@AMENITIESNAME", dataGridView1.Rows[i].Cells[1].Value);
                            CMD.Parameters.AddWithValue("@DESCRIPTION", dataGridView1.Rows[i].Cells[2].Value);
                            CMD.Parameters.AddWithValue("@CHECKBOX", dataGridView1.Rows[i].Cells[3].Value);
                            CMD.Parameters.AddWithValue("@AMOUNT", dataGridView1.Rows[i].Cells[4].Value);

                            CMD.ExecuteNonQuery();



                            // dataGridView1.Rows[lastCell.RowIndex].Cells["AMOUNT"].ReadOnly = true;
                        }
                    }
                }

            }
        }
    }
}
Posted
Updated 24-May-17 3:45am

Personally I wouldn't use the CellEnter or CellLeave events - the user could just be tabbing through the cells without intending to edit them.

I would use the CellBeginEdit and CellEndEdit events instead. Something like this might work (although you might want to do a little more checking for null references). Note I've assumed the Checkbox column is column 0
C#
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == 0)
    {
        return;
    }

    if(string.IsNullOrEmpty((dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex]).EditedFormattedValue.ToString()))
    {
        var cb = (dataGridView1.Rows[e.RowIndex].Cells[0]) as DataGridViewCheckBoxCell;
        cb.Value = false;
    }
}

private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
    if (e.ColumnIndex == 0)
    {
        return;
    }

    var cb =((DataGridViewCheckBoxCell)(dataGridView1.Rows[e.RowIndex].Cells[0])).Value;
    if(cb == null || !(bool)cb)
    {
        e.Cancel = true;
    }
}

There is a "gotcha" when using CellContentClick to capture the setting on/off of the Checkbox - If you look at this code snippet
C#
var a = ((dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex]) as DataGridViewCheckBoxCell).EditedFormattedValue;
var b = ((dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex]) as DataGridViewCheckBoxCell).Value;
var c = ((dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex]) as DataGridViewCheckBoxCell).FormattedValue;
Debug.Print("a{0}, b{1}, c{2}", a, b, c);
You get the following output when you first click on the Checkbox:
aTrue, b, cFalse
In other words we need to use EditedFormattedValue to get the value that we are moving to

To prevent editing of the cells you can use the ReadOnly property of the cells BUT you need to handle the situation of the user trying to edit columns on a new row without ticking the box - the easiest way is just to check the value of the Checkbox in the CellBeginEdit event as I did above. Note in that case we need to use the Value property of the cell.

To automatically set the focus to the next column you use the CurrentCell property of the DataGridView. So this might work:
C#
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{

    if (e.ColumnIndex != 0)
    {
        return;
    }

    var z = (bool)((dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex]) as DataGridViewCheckBoxCell).EditedFormattedValue;

    for (var i = 1; i < dataGridView1.Columns.Count; i++)
    {
        dataGridView1.Rows[e.RowIndex].Cells[i].ReadOnly = !z;
    }

    if (!z)
    {
        return;
    }
    dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[1];
}


Down to your final requirement
Quote:
if cell while leaving is not empty it has to store the data of that row in database
It's a PITA to work out what you are trying to do with so much commented out code, so consider the following points.
You need to make sure that whatever the user has entered is valid, so the CellLeave, CellValidating and RowValidating are not appropriate methods in which to put your database save code. Instead consider the following:
C#
private void dataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e)
{
    //The cell has been edited, the editing is finished with and the cell has been validated
    // NOW is the time to write the data for this CELL only to the database
    // BUT do you really want to ...
}

private void dataGridView1_RowValidated(object sender, DataGridViewCellEventArgs e)
{
    //The row has been edited, the editing is finished with and the row has been validated
    // NOW is the time to write the data for this *ROW* only to the database
    // BUT do you really want to ...
}

private void dataGridView1_Validated(object sender, EventArgs e)
{
    //The datagridview has been edited, the editing is finished with and the datagridview has been validated
    // NOW is the time to write ALL of the data for this *DATAGRIDVIEW* to the database
    // BUT do you really want to ...
}
private void btnSaveChanges_Click(object sender, EventArgs e)
{
    // The USER is telling you that they have finished editing.
    // NOW is the time to write ALL of the data for the DATAGRIDVIEW to the database
}
 
Share this answer
 
private async void dataGridView1_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
    {

        if (lastCell != null)
        {
            var lastAmtCell = dataGridView1.Rows[e.RowIndex].Cells["AMOUNT"];
            if (lastAmtCell.Value == true)
            {
                // MessageBox.Show("working");

                lastCell.Value = false;
            }
            else
            {
                // MessageBox.Show("working");

                lastCell.Value = true;
            }
        }

        var amountCell = dataGridView1.Rows[e.RowIndex].Cells["AMOUNT"];
        if (e.RowIndex > -1 && dataGridView1.CurrentCell == dataGridView1.Rows[e.RowIndex].Cells["CHECKBOX"])
        {

            if (amountCell.ReadOnly == true)

            {
                amountCell.ReadOnly = false;
                amountCell.Style.BackColor = Color.White;

            }



            else
            {
                dataGridView1.Rows[e.RowIndex].Cells["AMOUNT"].ReadOnly = true;
                amountCell.Style.BackColor = Color.Gray;

                //dataGridView1.Columns["AMOUNT"].Visible = true;

            }
            lastCell = dataGridView1.CurrentCell;
        }
    }
 
Share this answer
 
v3
Comments
saimanisha 25-May-17 0:12am    
this code is written already its there in my code .whats the use of that.its completely diff from my requirement

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900