简体   繁体   中英

How to map properties of inner/nested classes in DataGridView through BindingSource?

I have a separate project for Data layer and there are two basic classes there:

[Serializable]
public class NesInfo
{
    public string FileName { get; private set; }
    public string Directory { get; private set; }
    public MapperInfo MapperInfo { get; set; }
}

and

[Serializable]
public class MapperInfo
{
    public string Number { get; set; }
    public string Prop1{ get; set; }
    public string Prop2 { get; set; }
}

Now I want my DataGridView to Display columns like this:
[FileName][Directory][Number][Prop1][Prop2]

How I can achieve this using BindingSource?

I've tried using my BindingSource in my DataGridView, but instead of 5 columns, I get 3 (the nested class is treated like one column, where the inner properties should be there instead):

在此处输入图片说明

And I cannot select the inner properties of MapperInfo class when trying to add columns: 在此处输入图片说明

You can create a new class with all the properties that you want to be display in the grid and map it with your existing class either manually or using third-party libraries (ex. AutoMapper). Then bind the new class to Grid.

public class MyGridClass
{
    public string FileName { get; set; }
    public string Directory { get; set; }
    public string Number { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
}

NesInfo ni = ...

MyGridClass gc = new MyGridClass ( );
gc.FileName = ni.FileName;
gc.Directory = ni.Directory;
gc.Number = ni.MapperInfo.Number;
gc.Prop1 = ni.MapperInfo.Prop1;
gc.Prop2 = ni.MapperInfo.Prop2;

Use CellFormatting event handler. DataGridView.CellFormatting Event

private void dataGridView1_CellFormatting(object sender,
                                          DataGridViewCellFormattingEventArgs e)
{
    if (e.RowIndex < 0 || e.ColumnIndex < 0)
        return;
    DataGridViewColumn column = this.dataGridView1.Columns[e.ColumnIndex];
    //For getting right column you can compare to the index
    //Or as in this example comparing to the names of the predefined columns
    if (column.Name.Equals(this.ColumnMapperInfoNumber.Name) == true)
    {
        MapperInfo temp = e.Value as MapperInfo;
        if (temp != null)
            e.Value = temp.Number;
    }
    else if(column.Name.Equals(this.ColumnMapperInfoProp1.Name) == true)
    {
        MapperInfo temp = e.Value as MapperInfo;
        if (temp != null)
            e.Value = temp.Prop1;  
    }
    else if(column.Name.Equals(this.ColumnMapperInfoProp2.Name) == true)
    {
        MapperInfo temp = e.Value as MapperInfo;
        if (temp != null)
            e.Value = temp.Prop2;
    }        
}

Another way which can be used is overriding .ToString() method in your class,
because DataGridViewTextBoxColumn will execute this method on the bounded item for getting displayed text (that is why you see name of your class there).

[Serializable]
public class MapperInfo
{
    public string Number { get; set; }
    public string Prop1{ get; set; }
    public string Prop2 { get; set; }

    public override string ToString()
    {
        return this.Number + ", " + this.Prop1 + ", " + this.Prop2;
    }
}

But I afraid this approach isn't for you, because you want different properties in the different columns

Ended up creating a flat class used for grid view, and set up Mapping using AutoMapper from scratch:

private void Map(NesInfo ni,out RomInfoView romInfo)
    {
        Mapper.CreateMap<NesInfo, RomInfoView>()
            .ForMember(x => x.MapperNumber, options => options.MapFrom(src => src.MapperInfo.Number))
            .ForMember(x => x.Prop1, options => options.MapFrom(src => src.MapperInfo.Prop1))
            .ForMember(x => x.Prop2,
                options => options.MapFrom(src => src.MapperInfo.Prop2));
        romInfo = Mapper.Map<RomInfoView>(ni);
    }

As suggested as @Vidhyardhi Gorrepati

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