Darj
Darj

Reputation: 1403

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):

enter image description here

And I cannot select the inner properties of MapperInfo class when trying to add columns: enter image description here

Upvotes: 0

Views: 2682

Answers (3)

Darj
Darj

Reputation: 1403

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

Upvotes: 0

Fabio
Fabio

Reputation: 32445

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

Upvotes: 0

Vidhyardhi Gorrepati
Vidhyardhi Gorrepati

Reputation: 682

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;

Upvotes: 2

Related Questions