DataGridViewTextBoxCell.ReadOnly = true, but can s

2019-07-27 04:48发布

问题:

DataGridViewComboBoxCell.ReadOnly = true, but can still change the selected value has the same question but user was satisfied with an answer I can't implement.

I got a dataGridView with many columns, one of which is a checkBoxColumn, which should activate or deactivate another column with text:

Now, the code I got works perfect once the dataGridView is loaded: I click on the checkboxes and they work as expected.

The problem is that I want the dataGridView to disable AllergiesDescription cells that don't have their corresponding Allergies cell checked in load time. I wrote a code that should iterate over the rows and execute the disable cell code whenever an unchecked Allergies cell is found. But against all odds, it doesn't work! It sets all wanted properties to the cell (like readonly = true) but still the cell is editable:

Sharing my code here below:

    private void dataGridView_CellContentClick(object sender,
        DataGridViewCellEventArgs cellEvent)
    {
        if (cellEvent.ColumnIndex == AllergiesCheckBoxColumn.Index)
            toggleAllergiesDescriptionHabilitation(cellEvent.RowIndex);
    }

    private void toggleAllergiesDescriptionHabilitation(int rowIndex)
    {
        int columnIndex = AllergiesDescriptionTextBoxColumn.Index;
        DataGridViewRow row = dataGridView.Rows[rowIndex];
        var allergiesDescriptionCell = (DataGridViewTextBoxCell)row.Cells[columnIndex];
        var currentCell = (DataGridViewCheckBoxCell)dataGridView.CurrentCell;
        if ((bool)currentCell.EditedFormattedValue)
            enableCell(allergiesDescriptionCell);
        else
            disableCell(allergiesDescriptionCell);
    }

    private void enableCell(DataGridViewTextBoxCell cell)
    {
        cell.ReadOnly = false;
        cell.Style.BackColor = Color.White;
        cell.Style.ForeColor = Color.Black;
        cell.Style.SelectionBackColor = Color.Blue;
        cell.Style.SelectionForeColor = Color.White;
    }

    private void disableCell(DataGridViewTextBoxCell cell)
    {
        cell.ReadOnly = true;
        cell.Style.BackColor = Color.LightGray;
        cell.Style.ForeColor = Color.DarkGray;
        cell.Style.SelectionBackColor = Color.LightGray;
        cell.Style.SelectionForeColor = Color.DarkGray;
    }

That code works perfect as I said, whenever I check an Allergies checkBox the corresponding AllergiesDescription cell enables or disables as expected. But:

    public People(PersistenceManager persistenceManager)
    {
        InitializeComponent();
        //other stuff
        disableNotCheckedAllergiesDescription();
    }

    private void disableNotCheckedAllergiesDescription()
    {
        foreach (DataGridViewRow row in dataGridView.Rows)
        {
            Person person = (Person)row.DataBoundItem;
            if (person != null && !person.Allergies)
                disableNotCheckedAllergiesDescription(row);
        }
    }

    private void disableNotCheckedAllergiesDescription(DataGridViewRow row)
    {
        int columnIndex = AllergiesDescriptionTextBoxColumn.Index;
        var allergiesDescriptionCell = (DataGridViewTextBoxCell)row.Cells[columnIndex];
        disableCell(allergiesDescriptionCell);
    }

This doesn't work, as you can see, it only executes the disableCell code for each cell that should be disabled, when I debug, the unchecked rows enter the method disableCell correctly, and their readonly value is set to true correctly, but they are still editable.

回答1:

Setting the ReadOnly property of the DataGridCells seems to come to early when you call it from inside the constructor. Try moving your this call:

disableNotCheckedAllergiesDescription();

to the DataBindingComplete event instead.