在DataGridView中,如何将数组或列表(带有n
元素)绑定到n
DataGridViewTextBoxColumn?
也许它不是那么清楚,例如,我有一个班级:
public class DynamicNumberFieldsClass
{
public string FullName { get; set; }
public int[] Years { get; set; }
}
DataGridView应显示的预期格式:
FullName Year1 Year2 Year3...
Peter 11 12 13
Bryan 21 22 23
如果我必须使用反射,那对我来说没问题。
有什么想法吗?
谢谢!
彼得
P.S。:我们可以假设数组字段永远不会是null
。
我们甚至可以假设一旦会话开始就修复了数组中元素的数量,但是用户可以在“设置”中更改它,因此在下一个会话中,元素的数量可能不同。
答案 0 :(得分:0)
我假设您使用的是Windows窗体。通过将DataGridView放在Virtual Mode中,我至少能够以您显示的格式显示数据。您最好按照the entire walkthrough获得完整的解决方案,但这是我在快速测试中所做的(从散步中的示例中删除):
CellValueNeeded处理程序:
private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
// If this is the row for new records, no values are needed.
if (e.RowIndex == this.dataGridView1.RowCount - 1) return;
DynamicNumberFieldsClass objectInRow = (DynamicNumberFieldsClass)this._people[e.RowIndex];
// Set the cell value to paint using the DynamicNumberFieldsClass object retrieved.
switch (this.dataGridView1.Columns[e.ColumnIndex].Name)
{
case "FullName":
e.Value = objectInRow.FullName;
break;
default:
e.Value = objectInRow.Years[e.ColumnIndex - 1];
break;
}
}
其中_people是DynamicNumberFieldsClass的集合。
表单加载:
private void Form1_Load(object sender, EventArgs e)
{
this.dataGridView1.VirtualMode = true;
this.dataGridView1.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);
// Add columns to the DataGridView.
DataGridViewTextBoxColumn fullNameColumn = new
DataGridViewTextBoxColumn();
fullNameColumn.HeaderText = "FullName";
fullNameColumn.Name = "FullName";
this.dataGridView1.Columns.Add(fullNameColumn);
for (int i = 0; i < _numYears; i++)
{
DataGridViewTextBoxColumn yearIColumn = new
DataGridViewTextBoxColumn();
yearIColumn.HeaderText = "Year" + (i+1);
yearIColumn.Name = "Year" + (i+1);
this.dataGridView1.Columns.Add(yearIColumn);
}
this.dataGridView1.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
// Set the row count, including the row for new records.
this.dataGridView1.RowCount = 3; //two objects in _people and the empty row
}
其中_numYears是您提到的固定值。如果您至少有一个对象实例可用,则可以使用该实例中Years数组的大小作为循环限制器,这样它就完全是动态的。
如果类中包含任何其他属性,则需要扩展switch语句,当然还要添加更多错误检查。本演练演示了如何在DataGridView中支持编辑。
(我知道你问过如何绑定列,而不是强制它们的值,所以你可能希望能够装饰类定义,分配数据源,然后去。为此我首先考虑使用Reflection通过CustomTypeDescriptor and TypeDescriptionProvider等进行此操作,这是第二级属性可以绑定的方式。当然,数组的各个元素不会作为属性公开,所以这不是我想不出一种方法来支持你想要的自动生成列,但也许其他人会找到一个。)