我有一个DataGridView
,其DataSource
是DataTable
,有五列。如果我尝试访问列ReadOnly
属性,请执行以下操作:
datagridview.Columns[1].ReadOnly = true;
它会抛出NullReferenceExcpetion
。
我理解这是由于框架如何管理其自动生成的列,正如this question的答案所述。
我的问题是:当自动生成数据源时,如何只读列?
答案 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;
}
}
}