简体   繁体   中英

Bind nested object to DataGridView BindingSource

I have an XML file that I am able to bind to bind to the DataGridView using the following code:

XML

<entity>
    <primitive name"Name1" type="Type1" index="Index1" nullable="true" isKey="false" />
    <primitive name"Name2" type="Type2" index="Index2" nullable="true" isKey="false" />
 </entity>

C#

//The creation of columns here is explicit which is actually dynamic which I will show later
DataGridViewColumn nameColumn = new DataGridViewTextBoxColumn();
nameColumn.DataPropertyName = "Name";
nameColumn.Name = "Name";
dataGridViewPrimitives.Columns.Add(nameColumn);

DataGridViewCheckBoxColumn keyColumn = new DataGridViewCheckBoxColumn();
keyColumn.DataPropertyName = "IsKey";
keyColumn.Name = "Is Key";
dataGridViewPrimitives.Columns.Add(keyColumn);

//all other columns here

private void Bind()
{
    dataGridViewPrimitives.DataSource = null;
    bindingSourcePrimitives.DataSource = entity.Primitives;
    dataGridViewPrimitives.DataSource = bindingSourcePrimitives;
    /*
     * entity.Primitives is a collection of primitives parsed somewhere
     * but basically entity is an object with a member Collection<Primitive> Primitives
    /*
}

The code above works perfectly fine, the problem I have is when I added a nested tag into the XML which I have to display in another DataGridView

The new XML structure looks like this:

<entity>
    <primitive name"Name1" type="Type1" index="Index1" nullable="true" isKey="false" />
    <primitive name"Name2" type="Type2" index="Index2" nullable="true" isKey="false" />
    <staticData>
        <records>
            <record>
                <property name="StartDate" value="04/04/2017" />
                <property name="EndDate" value="04/04/2017" />
                <property name="Description" value="Very Good" />
            </record>
        </records>
    </staticData>
 </entity>

I'm dynamically creating the DataGridView columns based on the property.name so it looks like this:

StartDate    |     EndDate    |     Description
             |                |     

The problem right now is actually filling up this filling up this DataGridView with the values from the property.name in the XML

Just to give you an idea, this is how the class is structured.

public class Entity
{
    public Collection<Primitive> Primitives;
    public Collection<StaticData> StaticData;
}

public class StaticData
{
    public Collection<Records> Records;
}

public class Records
{
    public Collection<Record> Record;
}

public class Record
{
    public Collection<Property> Property;
}

Here's what I've tried so far:

 bindingSourceStaticData.DataSource = Entity.StaticData.FirstOrDefault().Records.FirstOrDefault().Record.FirstOrDefault().Property;
 dataGridViewStaticData.DataSource = bindingSourceStaticData;

And this is the result:

StartDate    |     EndDate    |     Description    |    Name        |    Value
             |                |                    |    StartDate   |    04/04/2017
             |                |                    |    EndDate     |    04/04/2017
             |                |                    |    Description |    Very Good

You see that it added new columns and filled in the rows instead of filling up the rows for the columns I created.

You could bind to a DataTable . You would have the ability to generate columns from an array of objects, which can come from your name attributes.

// populate DataTable columns
DataTable dt = new DataTable();
Collection<Property> properties = entity
    .StaticData.FirstOrDefault()
    .Records.FirstOrDefault()
    .Record.FirstOrDefault()
    .Property;
// from the collection of xml name attributes in the first record
dt.Columns.AddRange(properties.Select(p => new DataColumn(p.Name)).ToArray());

// populate DataTable rows
Collection<Record> records = entity
    .StaticData.FirstOrDefault()
    .Records.FirstOrDefault()
    .Record;
// create a row from each record, with the values from the xml value attribute
foreach (Record r in records)
{
    dt.Rows.Add(r.Property.Select(p => p.Value).ToArray());
}

// bind to the datatable
dataGridView1.DataSource = dt;

Note that the columns are generated from the first record, as you had done. Then I assume that the first record's properties are the same as all the other records' properties.

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