是否可以将复杂类型属性绑定到数据网格?

我如何将以下对象Car绑定到gridview?

公共类汽车
 {
    long Id {get; 组;}
   制造商Maker {get; 组;}
 }

公共类制造商
 {
    long Id {get; 组;}
   字符串名称{get; 组;}
 }

原始类型很容易绑定,但我发现无法为Maker显示任何内容。 我想让它显示Manufacturer.Name。 它甚至可能吗?

怎么办呢? 我是否还必须将ManufacturerId存储在Car中,然后使用制造商列表设置lookupEditRepository?

好吧…这个问题已经发布了回来,但我刚刚发现了一个相当不错的简单方法,通过在cell_formatting事件中使用reflection来检索嵌套属性。

是这样的:

private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { DataGridView grid = (DataGridView)sender; DataGridViewRow row = grid.Rows[e.RowIndex]; DataGridViewColumn col = grid.Columns[e.ColumnIndex]; if (row.DataBoundItem != null && col.DataPropertyName.Contains(".")) { string[] props = col.DataPropertyName.Split('.'); PropertyInfo propInfo = row.DataBoundItem.GetType().GetProperty(props[0]); object val = propInfo.GetValue(row.DataBoundItem, null); for (int i = 1; i < props.Length; i++) { propInfo = val.GetType().GetProperty(props[i]); val = propInfo.GetValue(val, null); } e.Value = val; } } 

就是这样! 您现在可以在列的DataPropertyName中使用熟悉的语法“ParentProp.ChildProp.GrandChildProp”。

是的,您可以创建TypeDescriptionProvider来完成嵌套绑定。 以下是MSDN博客的详细示例:

http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source。 ASPX

我在最近的一个应用程序中解决这个问题的方法是创建我自己的DataGridViewColumn和DataGridViewCell类,inheritance一个现有的类,如DataGridViewTextBoxColumn和DataGridViewTextBoxCell。

根据您想要的单元格类型,您可以使用其他如Button,Checkbox,ComboBox等。只需看看System.Windows.Forms中可用的类型。

单元格将它们的值作为对象处理,因此您可以将Car类传递给单元格的值。

重写SetValue和GetValue将允许您具有处理该值所需的任何其他逻辑。

例如:

 public class CarCell : System.Windows.Forms.DataGridViewTextBoxCell { protected override object GetValue(int rowIndex) { Car car = base.GetValue(rowIndex) as Car; if (car != null) { return car.Maker.Name; } else { return ""; } } } 

在列类中,您需要做的主要事情是将CellTemplate设置为自定义单元类。

 public class CarColumn : System.Windows.Forms.DataGridViewTextBoxColumn { public CarColumn(): base() { CarCell c = new CarCell(); base.CellTemplate = c; } } 

通过在DataGridView上使用这些自定义Column / Cells,它允许您向DataGridView添加许多额外function。

我使用它们来改变显示的格式,重写GetFormattedValue以将自定义格式应用于字符串值。

我还对Paint进行了覆盖,以便我可以根据值条件进行自定义单元格突出显示,根据值将单元格Style.BackColor更改为我想要的。

  public class Manufacturer { long Id {get; set;} String Name {get; set;} public override string ToString() { return Name; } } 

覆盖to string方法。

只需使用List并将DataMember设置为字符串“Maker.Name”,如果您希望DataKeyField使用car的ID,只需将其设置为“ID”即可。

 dataGrid.DataSource = carList; dataGrid.DataMember = "Maker.Name"; dataGrid.DataKeyField = "ID"; dataGrid.DataBind(); 

我知道这对转发器控制起作用,至少……

如果你想将特定的嵌套属性公开为绑定目标,那么Ben Hoffstein的回答( http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column- to-a-second-level-of-a-data-source.aspx )非常好。 引用的文章有点迟钝,但它有效。

如果您只想将列绑定到复杂属性(例如Manufacturer)并覆盖渲染逻辑,那么要么执行ManiacXZ推荐的操作,要么只是inheritanceBoundField并提供FormatDataValue()的自定义实现。 这类似于重写ToString(); 你得到一个对象引用,并返回你想要在网格中显示的字符串。

像这样的东西:

 public class ManufacturerField : BoundField { protected override string FormatDataValue(object dataValue, bool encode) { var mfr = dataValue as Manufacturer; if (mfr != null) { return mfr.Name + " (ID " + mfr.Id + ")"; } else { return base.FormatDataValue(dataValue, encode); } } } 

只需将ManufacturerField添加到网格中,将“Manufacturer”指定为数据字段,就可以了。

这是我工作的另一个选择:

   <%#Eval("Maker.Name")%>   

可能是ASP.NET 4.0特定的,但它的工作就像一个魅力!

我认为你可以做到以下几点:

 public class Car { public long Id {get; set;} public Manufacturer Maker {private get; set;} public string ManufacturerName { get { return Maker != null ? Maker.Name : ""; } } } public class Manufacturer { long Id {get; set;} String Name {get; set;} }