Abner
Abner

Reputation: 29

WinForms DataGridView Checkbox

I am trying to figure out how to set a cell in a dataGridView to ReadOnly.
The checkbox is being added by the boolean property. Therefore, I looking for tips how to accomplished the task of setting a cell to readonly based on the column with the boolean property.

Below is a snippet of my code.

[DisplayName("Lock")]
public bool RevenueLock { get; set; }

revenue = new DomesticCostRevenue()
{
RevenueLock = Convert.ToBoolean(values[10]),
Revenue = Convert.ToDouble(values[11])
};
domestic.Add(revenue);
}
CostRevenueGridView.DataSource = domestic;

This is what I've done but no success so far.

foreach (DataGridViewRow row in CostRevenueGridView.Rows)
{
if ((bool)row.Cells["RevenueLock"].Value == true)
{
row.Cells["Revenue"].ReadOnly = true;

//MessageBox.Show("Lock");
}
}

Upvotes: 1

Views: 376

Answers (3)

Abner
Abner

Reputation: 29

Thank for the help. I finally was able to solve my problem. The below snippet is my solution.

    private void CostRevenueGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
        foreach (DataGridViewRow row in CostRevenueGridView.Rows)
        {
            foreach (DataGridViewCell cell in row.Cells)
            {
                if (cell.ColumnIndex == 12)
                {
                    if (Convert.ToBoolean(CostRevenueGridView.Rows[row.Index].Cells[cell.ColumnIndex].Value))
                    {
                        row.Cells[11].ReadOnly = true;
                    }
                }

            }
        }
    }

Upvotes: 0

Reza Aghaei
Reza Aghaei

Reputation: 125332

You can set the whole column or the whole row or a specific cell read only:

  • Column: this.dataGridView1.Columns[1].ReadOnly = true;
  • Row: this.dataGridView1.Rows[0].ReadOnly = true;
  • Cell: this.dataGridView1.Rows[0].Cells[1].ReadOnly = true;

Test

Put the below code in a button click or somewhere else to show a form to you. In first row, the second cell will be read only, because the first cell value is true:

var f = new Form();
f.Controls.Add(new DataGridView
{
    Name = "g",
    Dock = DockStyle.Fill
});
f.Load += (se, ev) =>
{
    var g = ((Form)se).Controls["g"] as DataGridView;
    g.AutoGenerateColumns = true;
    g.AllowUserToAddRows = false;
    g.DataSource = new List<C1>
    {
        new C1{P1=true, P2="x"},
        new C1{P1=false, P2="y"},
    };
    foreach (DataGridViewRow row in g.Rows)
    {
        if ((bool)row.Cells["P1"].Value == true)
            row.Cells["P2"].ReadOnly = true;
    }
};
f.ShowDialog();

And here is the code for class C1:

public class C1
{
    public bool P1 { get; set; }
    public string P2 { get; set; }
}

Also the problem doesn't exist with DataTable:

f.Load += (se, ev) =>
{
    var g = ((Form)se).Controls["g"] as DataGridView;
    g.AutoGenerateColumns = true;
    g.AllowUserToAddRows = false;
    var dt = new DataTable();
    dt.Columns.Add("P1", typeof(bool));
    dt.Columns.Add("P2", typeof(string));
    dt.Rows.Add(true, "x");
    dt.Rows.Add(false, "y");
    g.DataSource = dt;
    foreach (DataGridViewRow row in g.Rows)
    {
        if ((bool)row.Cells["P1"].Value == true)
            row.Cells["P2"].ReadOnly = true;
    }
};

Upvotes: 1

Grant Winney
Grant Winney

Reputation: 66501

I recreated your issue by creating a DataTable, populating with two columns matching yours, and then using the foreach loop you posted. My results were the same as yours. The individual cells that were ReadOnly were still editable.

I'm not sure why this is, but since Reza got it to work with a List<T>, I assume it has something to do with a DataTable.

Try subscribing to the RowsAdded event, and moving your check into there. Column names may not work with this code... if not, use the column indexes instead.

private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
    for (int index = e.RowIndex; index <= e.RowIndex + e.RowCount - 1; index++)
    {
        var currentRow = dataGridView1.Rows[index];

        if (Convert.ToBoolean(currentRow.Cells[0].Value))
            currentRow.Cells[1].ReadOnly = true;
    }
}

Upvotes: 0

Related Questions