TEK
TEK

Reputation: 1265

Make auto generated column readonly in DataGridView

I have a DataGridView whose DataSource is a DataTable with five columns. If I attempt to access a column's ReadOnly property, like so:

datagridview.Columns[1].ReadOnly = true; 

It throws a NullReferenceExcpetion.

I understand this is due to how the framework manages its auto generated columns, as noted by the answer to this question.

My question is: How do I make a column(s) readonly when the data source is auto generated?

Upvotes: 2

Views: 1286

Answers (3)

Moumit
Moumit

Reputation: 9510

Make column read-only when column has been generated

    private void Form1_Load(object sender, EventArgs e)
    {

        List<Student> allStudent = new List<Student>();

        for (int i = 0; i < 10; i++)
        {
            allStudent.Add(new Student { Name = "Student" + i, Roll = i + 1 });
        }

        dataGridView1.AutoGenerateColumns = true;
        dataGridView1.DataSource = allStudent;

        //Edited to show column count
        MessageBox.Show("Column count is " + dataGridView1.Columns.Count);

        foreach (DataGridViewColumn column in dataGridView1.Columns)
        {
            column.ReadOnly = true;
        }

    }

    public partial class Student
    {
        public string Name { get; set; }
        public int Roll { get; set; }
    }

Upvotes: 0

balexandre
balexandre

Reputation: 75073

Can't really say why it's not working, but a simple test with this code:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.AutoGenerateColumns = true;
        dataGridView1.DataSource = GenerateData();

        dataGridView1.Columns[0].ReadOnly = true;
    }

    private List<DataSourceTest> GenerateData()
    {
        return new List<DataSourceTest>()
        {
            new DataSourceTest(1, "A"),
            new DataSourceTest(2, "B"),
            new DataSourceTest(3, "C"),
            new DataSourceTest(4, "D"),
            new DataSourceTest(5, "E"),
            new DataSourceTest(6, "F"),
        };
    }
}

public class DataSourceTest
{
    public DataSourceTest(int id, string name) { ID = id; Name = name; }
    public int ID { get; set; }
    public string Name { get; set; }
}

and making the gridview EditMode set to EditOnEnter so we can easily check if it's readonly or not, shows that it does the job well.

But if you still have issues, the best bet is to use an event, and the closest event for your question is the DataBindingComplete that will fire after the binding is done, so on that time, you will have full access to all your columns as they already bind to the gridview object.

double click on the event in the GridView control and add your readonly setter:

private void dataGridView1_DataBindingComplete(
    object sender, DataGridViewBindingCompleteEventArgs e)
{
    dataGridView1.Columns[0].ReadOnly = true;
}

Upvotes: 1

TEK
TEK

Reputation: 1265

In true TEK fashion, I figured out a solution to my own question:

To do this, you need to make use of the ColumnAdded event

datagridview.ColumnAdded += dataGridView_ColumnAdded;

Then in the event, you can check a column by name:

  private void dataGridView_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
  {
        if (e.Column is DataGridViewColumn)
        {
            DataGridViewColumn column = e.Column as DataGridViewColumn;
            column.ReadOnly = true;
            if (column.Name == "first_name")
            {
                column.ReadOnly = false;
            }
        }
  }

Upvotes: 0

Related Questions