是否可以将复杂类型属性绑定到数据网格?
我如何将以下对象Car绑定到gridview?
public class Car
{
long Id {get; set;}
Manufacturer Maker {get; set;}
}
public class Manufacturer
{
long Id {get; set;}
String Name {get; set;}
}
基本类型很容易绑定,但是我发现无法为Maker显示任何内容。我希望它显示Manufacturer.Name。可能吗?
有什么方法可以做到呢?我是否也必须在汽车中存储ManufacturerId,然后使用制造商列表设置lookupEditRepository?
解决方案
public class Manufacturer
{
long Id {get; set;}
String Name {get; set;}
public override string ToString()
{
return Name;
}
}
覆盖to字符串方法。
是的,我们可以创建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
只需使用一个List并将DataMember设置为字符串" Maker.Name",如果我们希望DataKeyField使用汽车的ID,只需将其设置为" ID"即可。
dataGrid.DataSource = carList; dataGrid.DataMember = "Maker.Name"; dataGrid.DataKeyField = "ID"; dataGrid.DataBind();
我知道至少在中继器控制中可以使用。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
我在最近的应用程序中解决此问题的方法是创建自己的DataGridViewColumn和DataGridViewCell类,这些类继承自诸如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上使用这些自定义列/单元格,它使我们可以向DataGridView添加很多额外的功能。
我使用它们通过覆盖GetFormattedValue来将自定义格式应用于字符串值来更改显示的格式。
我还对Paint进行了覆盖,以便可以根据值条件进行自定义单元格突出显示,从而根据值将单元格Style.BackColor更改为所需的值。
如果我们想将特定的嵌套属性作为绑定目标公开,则本霍夫斯坦(Ben Hoffstein)的答案(http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-到数据源的第二级属性.aspx)是相当不错的。所引用的文章有点晦涩,但可以。
如果我们只想将列绑定到复杂的属性(例如,制造商)并覆盖呈现逻辑,则可以按照ManiacXZ的建议进行操作,或者仅子类化BoundField并提供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"指定为数据字段,就可以了。
我认为我们可以执行以下操作:
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;}
}

