简体   繁体   English

如何通过BindingSource映射DataGridView中内部/嵌套类的属性?

[英]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: 现在,我希望我的DataGridView显示如下列:
[FileName][Directory][Number][Prop1][Prop2]

How I can achieve this using BindingSource? 如何使用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): 我尝试在DataGridView中使用BindingSource ,但得到的不是5列,而是3(嵌套类被视为一列,应在其中包含内部属性):

在此处输入图片说明

And I cannot select the inner properties of MapperInfo class when trying to add columns: 并且当尝试添加列时,我无法选择MapperInfo类的内部属性: 在此处输入图片说明

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). 您可以使用要在网格中显示的所有属性创建一个新类,然后手动或使用第三方库(例如AutoMapper)将其与现有类映射。 Then bind the new class to Grid. 然后将新类绑定到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. 使用CellFormatting事件处理程序。 DataGridView.CellFormatting Event DataGridView.CellFormatting事件

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, 可以使用的另一种方法是在您的类中重写.ToString()方法,
because DataGridViewTextBoxColumn will execute this method on the bounded item for getting displayed text (that is why you see name of your class there). 因为DataGridViewTextBoxColumn将在有界项上执行此方法以获取显示的文本(这就是为什么在那里看到类名的原因)。

[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: 最终创建了一个用于网格视图的平面类,并从头开始使用AutoMapper设置了Mapping:

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 如@Vidhyardhi Gorrepati所建议

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM