将组合框列数据绑定到每行的数据网格视图(而不是整个列)

时间:2011-05-06 19:47:29

标签: data-binding .net-3.5 datagridview datagridviewcombobox datagridviewcomboboxcell

有一些关于此的帖子,但经过几个小时的搜索,我仍然找不到我需要的东西。

以下帖子中的答案几乎让我得到了我想要的东西: Combobox for Foreign Key in DataGridView

问题1:

在产品具有许多许可证的示例中,我的数据库映射都是多对一关系,这意味着我的许可证类包含对Product类的引用。 License类没有ProductId的属性,因为可以通过Product引用检索它。我不想通过对Product和ProductId属性的引用来破坏License类,只是为了更容易在UI中进行绑定。

因此我无法将DataPropertyName设置为Id字段。它必须是类引用名称,如下所示:

DataGridViewComboBoxColumn dataGridViewComboBoxColumn = 
(DataGridViewComboBoxColumn)myDataGridView.Columns("LicenseComboBoxColumn");

dataGridViewComboBoxColumn.DataPropertyName = "License"; // not LicenseID

**** ****更新 通过将Product.Id指定为DataPropertyName,我能够在不创建ProductId属性的情况下使其部分工作:

dataGridViewComboBoxColumn.DataPropertyName = "License.Id";

但是,这样做会破坏数据绑定,导致我手动获取并设置单元格值。

我也看过有关绑定到DataGridView单元格的帖子,但是当我这样做并且数据源本身永远不会更新时,数据绑定会中断:

// populate the combo box with Products for each License

foreach (DataGridViewRow row in myDataGridViewProducts.Rows) 
{
    IProduct myProduct = row.DataBoundItem as IProduct;
    DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)row.Cells("myProductCol");
    cell.DataSource = getListOfILicenseObjectsFromDao(myProduct.Id);
    cell.Value = myProduct.License.Id;
}

也许我做错了什么,或者可能有不同的方式。任何人都可以帮忙吗?

问题2:

如何为每个产品显示不同的许可列表? 换句话说,许可证的组合框列表对于网格中的每个产品都是不同的。我想使用数据绑定来做到这一点,所以我不必自己获取和设置值。

1 个答案:

答案 0 :(得分:4)

我自己找到了答案。我刚才有同样的问题,并在我挖出的一些旧代码中找到了解决方案。解决方案是将一个Self属性添加到我想在组合框中进行数据绑定的对象(在上面的示例中它将是许可类)并将该属性用作ValueMember,如下所示:

foreach (DataGridViewRow row in myDataGridViewProducts.Rows) 
{
    IProduct myProduct = row.DataBoundItem as IProduct;
    DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)row.Cells("myProductCol");
    cell.DataSource = getListOfILicenseObjectsFromDao(myProduct.Id);
    cell.DataPropertyName = "License";        
    cell.DisplayMember = "Name";
    cell.ValueMember = "Self"; // key to getting the databinding to work
    // no need to set cell.Value anymore!
}

许可证类现在如下所示:

Public class License
{
    public string Name
    {
        get; set;
    }

    public ILicense Self
    {
        get { return this; }
    }

    // ... more properties
}

当然,我不得不使用名为Self的属性来“破解”Business类,但这比在Product类IMO中同时引用License和LicenseId属性要好得多(对程序员来说更少混淆)。此外,它使UI代码更加简单,因为无需手动获取和设置值 - 只需数据绑定和完成。