21

我将如何将以下对象 Car 绑定到网格视图?

公共级汽车
{
   长 ID {get; 放;}
   制造商 制造商 {get; 放;}
}

公共类 制造商
{
   长 ID {get; 放;}
   字符串名称 {get; 放;}
}

原始类型很容易绑定,但我发现无法为 Maker 显示任何内容。我希望它显示制造商名称。甚至可能吗?

有什么方法可以做到这一点?我是否也必须将 ManufacturerId 存储在 Car 中,然后设置一个带有制造商列表的 lookupEditRepository?

4

8 回答 8

28

好的,伙计们......这个问题已经发布了,但我刚刚找到了一种相当不错且简单的方法,方法是在 cell_formatting 事件中使用反射来检索嵌套属性。

像这样:

    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”。

于 2012-05-12T22:44:01.810 回答
12

是的,您可以创建一个 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

于 2008-09-23T14:30:22.387 回答
8

我在最近的一个应用程序中处理此问题的方法是创建我自己的 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 更改为我想要的。

于 2008-09-24T18:26:53.823 回答
5
    public class Manufacturer
    {
       long Id {get; set;}
       String Name {get; set;}

       public override string ToString()
       {
          return Name;
       }
    }

覆盖 to 字符串方法。

于 2008-09-23T14:27:20.507 回答
2

如果您想将特定的嵌套属性公开为绑定目标,那么 Ben Hoffstein 的回答(http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column- to-a-a-second-level-property-of-a-data-source.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”指定为数据字段,您就可以开始了。

于 2008-10-01T01:36:55.370 回答
2

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

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

我知道这在中继器控制中有效,至少......

于 2008-09-23T14:31:43.070 回答
2

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

<asp:TemplateColumn
    HeaderText="Maker">
    <ItemTemplate>
          <%#Eval("Maker.Name")%>
    </ItemTemplate>
</asp:TemplateColumn>

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

于 2011-03-09T18:30:25.530 回答
1

I would assume you could do the following:

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;}
}
于 2009-06-02T16:25:08.480 回答