【问题标题】:How to map properties of inner/nested classes in DataGridView through BindingSource?如何通过 BindingSource 映射 DataGridView 中内部/嵌套类的属性?
【发布时间】:2015-10-14 08:36:56
【问题描述】:

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

[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 列(嵌套类被视为一列,内部属性应该在那里):

在尝试添加列时,我无法选择 MapperInfo 类的内部属性:

【问题讨论】:

标签: c# winforms data-binding datagridview objectdatasource


【解决方案1】:

您可以创建一个包含您希望在网格中显示的所有属性的新类,然后手动或使用第三方库(例如 AutoMapper)将其与现有类映射。然后将新类绑定到 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;

【讨论】:

    【解决方案2】:

    使用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;
        }        
    }
    

    另一种可以使用的方法是在您的类中覆盖.ToString() 方法,
    因为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;
        }
    }
    

    但我担心这种方法不适合你,因为你想要不同列中的不同属性

    【讨论】:

      【解决方案3】:

      最终创建了一个用于网格视图的平面类,并从头开始使用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 所建议的那样

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-16
        • 1970-01-01
        • 2013-08-09
        • 1970-01-01
        • 2023-03-10
        • 2018-08-30
        相关资源
        最近更新 更多