c#中的DataGridView:将Properties作为列,将List的元素组合为列

时间:2015-03-09 09:20:41

标签: c# datagridview

我一直试图将这个问题包围得太久......我真的没有想法。

我需要实现的解释非常简单。这是我的对象,其中包含一个列表:

class MyObject
{
    public string property1 { get; set; }
    public string property2 { get; set; }
    public List<string> list { get; set; }
}

现在,我需要DataGridView的列看起来像这样:

[property1] | [property2] | [list_element1] | ... | [list_elementN]

数据绑定应该尽可能简单(我的真实对象有两个以上的非列表属性)。

我甚至尝试Reflection创建一个以list_element1, ... , list_elementN为属性的动态对象。我有点工作,但是创建DataGridView的新行存在某些问题,所以我放弃了这条道路。

我最好的选择是什么?

1 个答案:

答案 0 :(得分:1)

我想我找到了一种方法让你这样做...(我想明确表示我的代码确实非常容易出错,但我只想表明它有一线希望,所以请不要别我真的很喜欢这个)

假设你有这样的数据源:

List<MyObject> dataSource = new List<MyObject>
{
    new MyObject
    {
        ID = 1,
        Name = "Row1",
        List = new List<string>() {"item1", "item2", "item3"}
    },
    new MyObject
    {
        ID = 2,
        Name = "Row2",
        List = new List<string>() {"item4", "item5", "item6"}
    },
    new MyObject
    {
        ID = 3,
        Name = "Row3",
        List = new List<string>() {"item7", "item8", "item9"}
    }
};

您可以使用现有MyObject创建的动态数据源。 (我使用了ExpandoObject,因此我可以动态添加属性)

List<dynamic> dynamicSource = new List<dynamic>();
foreach (var data in dataSource)
{
    dynamic o = new ExpandoObject();
    // assigning properties we already know
    o.ID = data.ID;
    o.Name = data.Name;

    int idx = 0; // just a counter. you could also do this with a for-loop of course
    foreach (var item in data.List)
    {
        var dict = o as IDictionary<string, Object>; // cast expando object just to get the properties as key and value pairs in a dictionary
        dict.Add("ItemNr" + idx, item);
        idx++;
    }
    dynamicSource.Add(o);
}

现在有一个我发现here的扩展方法,此时非常方便

    public static DataTable ToDataTable(this IEnumerable<dynamic> items)
    {
        var data = items.ToArray();
        if (data.Count() == 0) return null;

        var dt = new DataTable();
        foreach (var key in ((IDictionary<string, object>)data[0]).Keys)
        {
            dt.Columns.Add(key);
        }
        foreach (var d in data)
        {
            dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
        }
        return dt;
    }

现在我们可以将数据源添加到DataGridView中,如下所示:

var dataTable = Extensions.ToDataTable(dynamicSource);
dataGridView1.DataSource = dataTable;

现在应正确分配。 我测试过,添加行应该不是问题。

如果你想要取回你的数据源,你必须采取以下小方法:

private List<MyObject> ConvertBackToObject(DataTable dataTable)
    {
        // basically the same procedure as assigning

        List<MyObject> listMyDataSource = new List<MyObject>();
        foreach (DataRow row in dataTable.Rows)
        {
            MyObject myObject = new MyObject
            {
                ID = Convert.ToInt16(row["ID"]),
                Name = row["Name"].ToString(),
                List = new List<string>()
            };

            foreach (var column in dataTable.Columns.Cast<DataColumn>().Where(col => col.ColumnName.StartsWith("ItemNr")))
            {
                myObject.List.Add(row[column].ToString());
            }

            listMyDataSource.Add(myObject);
        }

        return listMyDataSource;
    }

引导我们(实际上获取数据源):

DataTable dataTable = dataGridView1.DataSource as DataTable;
// do some null checking here
List<MyObject> myObjects = ConvertBackToObject(dataTable);

这应该为您提供MyObject的更新列表(您现在可以使用它来将数据插入数据库)。

希望以某种方式明确并帮助它。