简体   繁体   中英

How to bind a variable-size list of objects containing another variable-size list of objects of to DataGridView in C#

How to bind a variable-size list of objects (here called Record) containing another variable-size list of objects (here called Field) to DataGridView in a way that each the Field object in the inner list bind to a cell (through Value property) and each of the Record object in the outer list bind to a row. The idea is to make a DataGridView dynamically with a variable number of columns based on the number of items in the inner list for each Record object. Here is my code for Record class:

public class Record
    {
        public List<Field> Fields { get; set; }
    }

and the Field class:

public class Field
    {
public String Name { get; set; }        
public String Value { get; set; }        
    }

in the main program I have something like:

    public List<Record> Records{ get; set; }

The Records list get filled programmatically and each Record in the list has the same amount of objects in its Fields list. Now I want to bind this data to a DataGridView in a way that each Record object in the outer list shows as a row in the table where each of its Fields is aa cell in the DataGridView. Is that possible? If so, how can I do it?

You can transform it to list of DataGridViewRow and add those the the DataGridView

First you need to set the columns (this assumes you have a first record at all):

foreach (Field field in this.Records.First().Fields) 
{ 
    dgv.Columns.Add(field.Name, field.Name); 
}

Then using LINQ transform each Record to DataGridViewRow

IEnumerable<DataGridViewRow> rows = this.Records.Select(rec =>
{
    var row = new DataGridViewRow();
    row.SetValues(rec.Fields.Select(field => field.Value));
    return row;
});

And finally load them to the DataGridView :

dgv.Rows.Add(rows);

If you want to use DataSource you will have to create a DataTable out of it.
You can create and extension method and use it like this:

dgv.DataSource = this.Records.ToDataTable();

The extension class:

public static class RecordListExtensions
{
    public static DataTable ToDataTable(this List<Record> records)
    {
        DataTable table = new DataTable();
        foreach (var field in records.First().Fields) { table.Columns.Add(field.Name); }

        foreach (var record in records)
        {
            table.Rows.Add(record.Fields.Select(field => field.Value).ToArray());
        }

        return table;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM