C# DatagGridViewColumn.DataPropertyName是否为数组元素?

C# DatagGridViewColumn.DataPropertyName是否为数组元素?,c#,.net,datagridview,C#,.net,Datagridview,我正在使用DataGridView将其数据源绑定到一个列表,并为每个列指定属性 例如: DataGridViewTextBoxColumn colConcept = new DataGridViewTextBoxColumn(); DataGridViewCell cell4 = new DataGridViewTextBoxCell(); colConcept.CellTemplate = cell4; colConce

我正在使用DataGridView将其数据源绑定到一个列表,并为每个列指定属性

例如:

 DataGridViewTextBoxColumn colConcept = new DataGridViewTextBoxColumn();
            DataGridViewCell cell4 = new DataGridViewTextBoxCell();
            colConcept.CellTemplate = cell4;
            colConcept.Name = "concept";
            colConcept.HeaderText = "Concept";
            colConcept.DataPropertyName = "Concept";
            colConcept.Width = 200;
            this.dataGridViewBills.Columns.Add(colConcept);
{…分配其他列…}

最后

 this.dataGridViewBills.DataSource=billslist; //billslist is List<Bill>
this.dataGridViewBills.DataSource=billslist//账单列表是一张清单
显然,类Bill有一个名为Concept的属性,每个列有一个属性

好的,现在我的问题是,Bill应该有和数组/List/whateverdynamicsizecontainer的字符串,称为Years

假设每个账单都有相同的年数。Count,但只有在运行时才知道。因此,我不能指定像Bill.FirstYear这样的属性来获取账单。Years[0],Bill.SecondYear来获取账单。Years[1]。。。等并将其绑定到每列

我的想法是,现在我想要一个具有动态列数(在运行时已知)的网格,每一列都用Bill.Years列表中的字符串填充。我可以根据Bill.Years.Count在运行时循环向网格中添加列,但是可以将它们绑定到Bill.Years列表包含的每个字符串吗

我不确定我是否足够清楚

理想情况下,清单上的2张账单的结果是这样的,每张账单的结果是3年:

--------------------------------------GRID HEADER------------------------------- NAME CONCEPT YEAR1 YEAR2 YEAR3 --------------------------------------GRID VALUES------------------------------- Bill1 Bill1.Concept Bill1.Years[0] Bill1.Years[1] Bill1.Years[2] Bill2 Bill2.Concept Bill2.Years[0] Bill2.Years[1] Bill2.Years[2] --------------------------------------网格头------------------------------- 名称概念年份1年份2年份3 --------------------------------------网格值------------------------------- Bill1 Bill1.概念Bill1.年[0]Bill1.年[1]Bill1.年[2] Bill2 Bill2.概念Bill2.年[0]Bill2.年[1]Bill2.年[2] 我总是可以忘记数据源,手动编写每个单元格,就像MSFlexGrid过去喜欢的那样,但是如果可能的话,我希望使用DataGridView的绑定功能


有什么想法吗?非常感谢。

您可以使用反射来设置和填充DataGridView。我用一种类型完成了这项工作,但我不明白为什么它不能扩展到您的数据结构

要设置DataGridView,请执行以下操作:

// Create the columns based on the data in the album info - get by reflection
var ai = new AlbumInfo();
Type t = ai.GetType();

dataTable.TableName = t.Name;

foreach (PropertyInfo p in t.GetProperties())
{
    // IF TYPE IS AN ARRAY (OR LIST) THEN ADD A COLUMN FOR EACH ELEMENT

    var columnSpec = new DataColumn();

    // If nullable get the underlying type
    Type propertyType = p.PropertyType;
    if (IsNullableType(propertyType))
    {
        var nc = new NullableConverter(propertyType);
        propertyType = nc.UnderlyingType;
    }
    columnSpec.DataType = propertyType;
    columnSpec.ColumnName = p.Name;
    dataTable.Columns.Add(columnSpec);
}

dataGridView.DataSource = dataTable;
// Add album info to table - add by reflection
var ai = new AlbumInfo();
Type t = ai.GetType();
// WOULD NEED TO INCREASE BY LENGTH OF ARRAY
var row = new object[t.GetProperties().Length];

int index = 0;
foreach (PropertyInfo p in t.GetProperties())
{
    // IF TYPE IS AN ARRAY (OR LIST) THEN ADD EACH ELEMENT

    row[index++] = p.GetValue(info, null);
}

dataTable.Rows.Add(row);
然后,要填充DataGridView:

// Create the columns based on the data in the album info - get by reflection
var ai = new AlbumInfo();
Type t = ai.GetType();

dataTable.TableName = t.Name;

foreach (PropertyInfo p in t.GetProperties())
{
    // IF TYPE IS AN ARRAY (OR LIST) THEN ADD A COLUMN FOR EACH ELEMENT

    var columnSpec = new DataColumn();

    // If nullable get the underlying type
    Type propertyType = p.PropertyType;
    if (IsNullableType(propertyType))
    {
        var nc = new NullableConverter(propertyType);
        propertyType = nc.UnderlyingType;
    }
    columnSpec.DataType = propertyType;
    columnSpec.ColumnName = p.Name;
    dataTable.Columns.Add(columnSpec);
}

dataGridView.DataSource = dataTable;
// Add album info to table - add by reflection
var ai = new AlbumInfo();
Type t = ai.GetType();
// WOULD NEED TO INCREASE BY LENGTH OF ARRAY
var row = new object[t.GetProperties().Length];

int index = 0;
foreach (PropertyInfo p in t.GetProperties())
{
    // IF TYPE IS AN ARRAY (OR LIST) THEN ADD EACH ELEMENT

    row[index++] = p.GetValue(info, null);
}

dataTable.Rows.Add(row);

这正是我使用的代码,因此您必须修改代码以处理年度数组/列表。

我最近遇到了同样的问题。我最终使用了DataGridView的虚拟模式,而不是绑定到数据源。它没有与绑定完全相同的特性,但它仍然比手动填充每个单元格强大得多

在虚拟模式下,DataGridView将在需要显示单元格时触发事件,这基本上意味着您可以随意填充单元格:

    private void my_init_function() {
        datagridview.VirtualMode = true;
        datagridview.CellValueNeeded += new System.Windows.Forms.DataGridViewCellValueEventHandler(datagridview_CellValueNeeded);
    }

    private void datagridview_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        e.Value = get_my_data(e.RowIndex, e.ColumnIndex);
    }

很抱歉撞到这个。我真的需要知道这是否真的可能。谢谢。