Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataGridView: Apply an edit to all selected rows

I have a DataGridView that's bound to a list of POCO objects. One of the POCO properties is a bool, that's represented by a checkbox. What I'd like is to be able to select multiple rows, then when I click one of the checkboxes, all the highlighted rows have their check boxes checked. By way of example, if you're using TFS under VS 2010, I'm trying to replicate the behaviour on the Pending Changes screen.

My problem is that I can't find a suitable event to listen to. Most DataGridView click events seem to operate at the Column/Row level, and I want something that fires when you click the checkbox. CellContentClick comes the closest, but that fires after the rows have been unselected, so that's not going to work.

Does anyone have any suggestions?

like image 227
TarkaDaal Avatar asked Mar 14 '12 13:03

TarkaDaal


2 Answers

You can use CurrentCellDirtyStateChanged for when Checkbox value has changed. But when this event triggers, the selectedrows will be gone. All you should do is to save selectedrows before it.

A simple sample: you can complete it easily.

DataGridViewSelectedRowCollection selected;

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    DataGridView dgv = (DataGridView)sender;
    DataGridViewCell cell = dgv.CurrentCell;
    if (cell.RowIndex >= 0 && cell.ColumnIndex == 1) // My checkbox column
    {
        // If checkbox value changed, copy it's value to all selectedrows
        bool checkvalue = false;
        if (dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue != null && dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue.Equals(true))
            checkvalue = true;

        for (int i=0; i<selected.Count; i++)
            dgv.Rows[selected[i].Index].Cells[cell.ColumnIndex].Value = checkvalue;
    }

    dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    selected = dataGridView1.SelectedRows;
}
like image 90
Mbt925 Avatar answered Nov 12 '22 18:11

Mbt925


This is not a nice design, but you can try to use the MouseDown event (which will trigger before the grid change the selection) and HitTest (to know where the user is clicking):

private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
    var hitTest = this.dataGridView1.HitTest(e.X, e.Y);
    if (hitTest.Type == DataGridViewHitTestType.Cell && hitTest.ColumnIndex == 0 /* set correct column index */)
    {
        foreach (DataGridViewRow row in this.dataGridView1.Rows)
        { 
            // Toggle
            row.Cells[0].Value = !((bool)row.Cells[0].Value);
        }
    }
}
like image 34
Fabske Avatar answered Nov 12 '22 20:11

Fabske