在 DataGridView 中将自动生成的列设置为只读
Make auto generated column readonly in DataGridView
我有一个 DataGridView
,它的 DataSource
是一个有五列的 DataTable
。如果我尝试访问列的 ReadOnly
属性,像这样:
datagridview.Columns[1].ReadOnly = true;
它抛出 NullReferenceExcpetion
.
我知道这是由于框架如何管理其自动生成的列,如对 this question 的回答所述。
我的问题是:如何在自动生成数据源时将列设置为只读?
生成列后将列设置为只读
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; }
}
以真正的 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;
}
}
}
无法真正说明为什么它不起作用,但使用以下代码进行简单测试:
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;
}
我有一个 DataGridView
,它的 DataSource
是一个有五列的 DataTable
。如果我尝试访问列的 ReadOnly
属性,像这样:
datagridview.Columns[1].ReadOnly = true;
它抛出 NullReferenceExcpetion
.
我知道这是由于框架如何管理其自动生成的列,如对 this question 的回答所述。
我的问题是:如何在自动生成数据源时将列设置为只读?
生成列后将列设置为只读
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; }
}
以真正的 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;
}
}
}
无法真正说明为什么它不起作用,但使用以下代码进行简单测试:
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;
}