Enable/Disable Button according to Checkbox value in a Datagridview

Asked

Viewed 2,851 times

3

A form in an application Windows Forms with C# displays a DataGridView with Checkbox. When one of Checkbox is marked I want to enable a certain button. If any Checkbox is marked I want to disable.

Try it like this:

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    bool marcado = false;
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell)dataGridView1.CurrentRow.Cells["chk"];
        if (chk.Value == chk.TrueValue)
        {
            marcado = true;
            break;
        }
    }

    if (marcado)
        button1.Enabled = true;
    else
        button1.Enabled = false;
}

And it didn’t work.

I tried to use in the CellValueChanged and also not working.

How to solve this problem.

  • I am without Visual Studio to test, but try to change DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell)dataGridView1.CurrentRow.Cells["chk"]; for DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell)row.Cells["chk"];, if it works I’ll create an answer!

  • @Matthew It hasn’t worked yet. The values chk.Value and chk.TrueValue are with Value = null. I think I’m using the wrong method. But it was worth the help.

2 answers

2


You can do this using the event CellValueChanged that way:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    // se a célula alterada for a célula de interesse (1.)
    if (dataGridView1.Columns[e.ColumnIndex].Name.Equals("chk"))
    {
        bool marcado = false;
        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell)row.Cells["chk"]; // (2.)
            // se a célula estiver marcada
            if ((bool)(chk.Value ?? false) == true) // (3.) e (4.)
            {
                marcado = true;
                break;
            }
        }

        if (marcado)
            button1.Enabled = true;
        else
            button1.Enabled = false;
    }
}

Follow some points of attention:

  1. I used a if before checking the values of DataGridViewCheckBoxCell to prevent verification from occurring in all columns.
  2. As I said in the comments, it was necessary to amend dataGridView1.CurrentRow for row, for otherwise their for would not run all lines, but rather only the current line (referring to altered cell).
  3. The ?? serves to check if the operator left of it is null, if that is, returns the value on the right, otherwise returns the value on the left, to know more see What is the meaning of the operator "??".
  4. The estate TrueValue should be used differently, as I do not know exactly how you are using the DataGridView, I preferred not to use it, but you can see an example here.

I don’t know exactly what volume of data you will be working on, but do this for every time a cell is checked/unchecked, you probably won’t perform well, I thought of another solution, maybe you need to improve it, but already serves as a starting point.

Create a global variable private int numeroCelulasMarcadas = 0;, this variable will serve as a marked cell counter, in the event RowsAdded of DataGridView, do so:

private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
    DataGridViewCheckBoxCell chk =
        (DataGridViewCheckBoxCell)dataGridView1.Rows[e.RowIndex].Cells["chk"];

    if ((bool)(chk.Value ?? false) == true)
    {
        numeroCelulasMarcadas++;
    }
}

Now at the event CellValueChanged put this:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    // se a célula alterada for a célula de interesse
    if (dataGridView1.Columns[e.ColumnIndex].Name.Equals("chk"))
    {
        DataGridViewCheckBoxCell chk = 
            (DataGridViewCheckBoxCell)dataGridView1.Rows[e.RowIndex].Cells["chk"];

        if ((bool)chk.Value == true)
        {
            numeroCelulasMarcadas++;
        }
        else
        {
            numeroCelulasMarcadas--;
        }

        if (numeroCelulasMarcadas == 0)
        {
            button1.Enabled = false;
        }
        else
        {
            button1.Enabled = true;
        }
    }
}

Remember that this solution that I passed last is a starting point, it may be necessary to adjust something to work correctness in the context of your application.

  • The post has important information, but it hasn’t worked yet. Using any of the code options the method CellValueChanged to mark the first CheckBox it is not fired. Nor am I concerned about the performance at first, as it would be few records.

  • @Jota, after changing the cell value, you tried to press ENTER or leave the cell? Because I tested it several times before posting the answer and it worked perfectly!

  • I didn’t know I had to type Enter, really works. The problem is that the user does not want to type the Enter. kkkk Cracking your head and with what you posted, I got a solution that works only with the click using the CellContentClick and CellContentDoubleClick. But it was worth the help and the shared knowledge.

  • you can accept the answer if you think I helped you achieve the purpose of the question or you can create and accept your own answer with the solution you found, detailing how you did it.

  • The two solutions can be considered correct. kkk I’ll see what I do. Thanks again.

0

The solution that Matthew proposed works, but you have to press the button Enter, in my case the user just wanted to click on CheckBox, then I used the following solution:

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.Columns[e.ColumnIndex].Name.Equals("chk"))
    {
        ManipulaBotao();
    }
}

private void dataGridView1_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.Columns[e.ColumnIndex].Name.Equals("chk"))
    {
        ManipulaBotao();
    }
}

private void ManipulaBotao()
{
    button1.Enabled = false;
    foreach (DataGridViewRow dr in dataGridView1.Rows)
    {
        if (bool.Parse(dr.Cells["chk"].EditedFormattedValue.ToString()))
        {
            button1.Enabled = true;
            break;
        }
    }
}

So just by clicking on CheckBox control is enabled/disabled.

It is worth noting that in my case the number of lines is small so it does not affect the performance, as was very well remembered in the post of Matthew.

Note the use of the method CellContentDoubleClick, otherwise it does not work as expected.

  • the main factor to have worked is the property EditedFormattedValue, because he had tried at this event as well, but using the property Value, that did not return the current value but what was when entered the cell.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.