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

时间:2020-03-06 14:36:06  来源:igfitidea点击:

我如何将以下对象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;}
}