如何通过BindingSource映射DataGridView中inner/nested类的属性?

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

我有一个单独的数据层项目,那里有两个基本的 class:

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

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

现在我希望我的 DataGridView 显示这样的列:
[FileName][Directory][Number][Prop1][Prop2]

如何使用 BindingSource 实现此目的?

我试过在我的 DataGridView 中使用我的 BindingSource,但我得到的不是 5 列,而是 3(嵌套的 class 被视为一列,内部属性应该在那里相反):

并且在尝试添加列时我无法 select MapperInfo class 的内部属性:

您可以使用要在网格中显示的所有属性创建一个新的 class,然后手动或使用第三方库(例如自动映射器)。然后将新的 class 绑定到 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;

使用CellFormatting 事件处理程序。 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;
    }        
}

另一种可以使用的方法是覆盖 class、
中的 .ToString() 方法 因为 DataGridViewTextBoxColumn 将在有界项目上执行此方法以获取显示的文本(这就是为什么您会在此处看到 class 的名称)。

[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;
    }
}

但恐怕这种方法不适合你,因为你想在不同的列中使用不同的属性

最终创建了一个用于网格视图的平面 class,并从头开始使用 AutoMapper 设置映射:

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);
    }

如@Vidhyardhi Gorrepati 所建议