0

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

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Darj
  • 1,403
  • 1
  • 17
  • 47

3 Answers3

2

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;
0

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

Fabio
  • 31,528
  • 4
  • 33
  • 72
0

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

Darj
  • 1,403
  • 1
  • 17
  • 47