在DataGridView中使自动生成的列只读

时间:2016-03-09 11:34:28

标签: c# winforms datagridview .net-4.6

我有一个DataGridView,其DataSourceDataTable,有五列。如果我尝试访问列ReadOnly属性,请执行以下操作:

datagridview.Columns[1].ReadOnly = true; 

它会抛出NullReferenceExcpetion

我理解这是由于框架如何管理其自动生成的列,正如this question的答案所述。

我的问题是:当自动生成数据源时,如何只读列?

3 个答案:

答案 0 :(得分:1)

无法解释为什么它不起作用,而是使用此代码进行简单测试:

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; }
}

并将gridview EditMode设置为EditOnEnter,以便我们可以轻松检查它是否只读,表明它能很好地完成工作。

但如果您仍然遇到问题,最好的办法是使用一个事件,而问题的最接近的事件是绑定完成后会触发的DataBindingComplete,所以在那个时候,您将拥有对所有列的完全访问权限,因为它们已经绑定到gridview对象。

双击GridView控件中的事件并添加只读的setter:

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

答案 1 :(得分:0)

在生成列时使列成为只读

    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; }
    }

答案 2 :(得分:0)

以真正的TEK方式,我想出了一个解决我自己问题的方法:

为此,您需要使用ColumnAdded事件

datagridview.ColumnAdded += dataGridView_ColumnAdded;

然后,在事件中,您可以按名称检查列:

  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;
            }
        }
  }