【问题标题】:Make auto generated column readonly in DataGridView在 DataGridView 中使自动生成的列只读
【发布时间】:2016-03-09 11:34:28
【问题描述】:

我有一个DataGridView,其DataSource 是一个有五列的DataTable。如果我尝试访问列的 ReadOnly 属性,如下所示:

datagridview.Columns[1].ReadOnly = true; 

它会抛出一个NullReferenceExcpetion

我知道这是由于框架如何管理其自动生成的列,正如对this question 的回答所指出的那样。

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

【问题讨论】:

  • 您尝试过使用DataBindingComplete 事件吗?我几乎可以肯定,当该事件被触发时,您已经可以访问所有自动生成的列......试一试。只需打开事件面板并双击事件,然后调试并检查列。
  • @balexandre 是的,这也有效!让它成为一个答案,我会接受它。

标签: c# winforms datagridview .net-4.6


【解决方案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 控件中的事件并添加您的只读设置器:

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

【讨论】:

  • 这是一个令人头疼的问题,但 DataBindingComplete 事件的使用对我有用。显然,我在沿途某处启用了一些属性标志,这导致了我的问题。但是,在这和我的回答之间,我的问题得到了解决。谢谢。
【解决方案2】:

以真正的 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;
            }
        }
  }

【讨论】:

    【解决方案3】:

    当列已生成时将列设为只读

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

    【讨论】:

    • 因为它使用AutoGeneratedColumns,所以列数总是返回0,这意味着循环的内容永远不会执行。检查datagridview.Columns.Count。不过,感谢您的回答。
    • @Momit 列数返回 0。抱歉,不知道该说什么。
    • @TEK .. 是否仍然显示 0(我放置消息框的位置).. 但这是不可能的 .. 直到 allStudent 变量为 null .. 我的示例显示它@987654326 @
    • 我认为这是我使用 DataGridView 的问题,我可能无意中切换了一个属性。 :)
    猜你喜欢
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多