mardi 20 avril 2021

How to toggle all checkboxes in all selected rows when one checkbox clicked in DataGridView

It took me a lot of time to find solution how to toggle all checkboxes of a DataGridViewCheckBoxColumn in all selected rows in DataGridView when one of them clicked.

I would like to share the solution with others (C++/CLI):

DataGridViewSelectedRowCollection ^previousDataGridView_SelectedRowCollection;

System::Void SetRedraw(Control ^control, Boolean value)
{
    SendMessage(static_cast<HWND>(control->Handle.ToPointer()), WM_SETREDRAW, value, 0);
}

System::Void SuspendDrawing(Control ^control)
{
    SetRedraw(control, false);
}

System::Void ResumeDrawing(Control ^control, Boolean redraw = true)
{
    SetRedraw(control, true);
    if (redraw)
        control->Refresh();
}

private: System::Void dataGridView_CellMouseDown(System::Object^ sender, System::Windows::Forms::DataGridViewCellMouseEventArgs^ e)
{
    if (e->RowIndex < 0 || e->ColumnIndex < 0)
        return;
    previousDataGridView_SelectedRowCollection =
        e->ColumnIndex == ColumnCheck->Index &&
        dataGridView->SelectedRows->Count > 1 &&
        dataGridView[e->ColumnIndex, e->RowIndex]->GetContentBounds(e->RowIndex).Contains(e->X, e->Y)
    ?
        dataGridView->SelectedRows
    :
        nullptr;
}

private: System::Void dataGridView_CellContentClick(System::Object^ sender, System::Windows::Forms::DataGridViewCellEventArgs^ e)
{
    if (e->RowIndex < 0
        || e->ColumnIndex < 0
        || e->ColumnIndex != ColumnCheck->Index)
        return;
    if (dataGridView->CurrentRow->Selected && (previousDataGridView_SelectedRowCollection || (previousDataGridView_SelectedRowCollection = dataGridView->SelectedRows)->Count > 1) && previousDataGridView_SelectedRowCollection->Contains(dataGridView->CurrentRow))
    {
        SuspendDrawing(dataGridView);
        try
        {
            DataGridViewCell ^currentCell = dataGridView->CurrentCell;
            Boolean isSelected;
            if (currentCell->ReadOnly)
                currentCell = nullptr;
            else
            {
                dataGridView->EndEdit();
                isSelected = safe_cast<Boolean>(currentCell->Value);
            }
            for each (DataGridViewRow ^dataGridViewRow in previousDataGridView_SelectedRowCollection)
            {
                DataGridViewCell ^dataGridViewCell = dataGridViewRow->Cells[e->ColumnIndex];
                if (currentCell && !dataGridViewCell->ReadOnly)
                    dataGridViewCell->Value = isSelected;
                dataGridViewCell->Selected = true;
            }
        }
        finally
        {
            ResumeDrawing(dataGridView);
        }
    }
    previousDataGridView_SelectedRowCollection = nullptr;
}

Here is a similar request

I hope this helps someone.




Aucun commentaire:

Enregistrer un commentaire