Data binding 将combobox列数据绑定到每行(而不是整列)的datagridview

Data binding 将combobox列数据绑定到每行(而不是整列)的datagridview,data-binding,.net-3.5,datagridview,datagridviewcombobox,datagridviewcomboboxcell,Data Binding,.net 3.5,Datagridview,Datagridviewcombobox,Datagridviewcomboboxcell,有一些帖子是关于这个的,但是经过几个小时的搜索,我仍然找不到我需要的东西 以下帖子中的答案几乎满足了我的需求: 问题1: 在一个产品有多个许可证的示例中,我的数据库映射都是多对一关系,这意味着我的许可证类持有对产品类的引用。许可证类没有ProductId的属性,因为可以通过产品引用检索该属性。我不想为了使UI中的绑定更容易而同时使用Product引用和ProductId属性来破坏License类 因此,我无法将DataPropertyName设置为Id字段。它必须是类引用名称,如下所示: Da

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

以下帖子中的答案几乎满足了我的需求:

问题1:

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

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

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

dataGridViewComboBoxColumn.DataPropertyName = "License"; // not LicenseID
dataGridViewComboBoxColumn.DataPropertyName = "License.Id";
****更新**** 通过将Product.Id指定为DataPropertyName,我可以在不创建ProductId属性的情况下部分实现此功能,如下所示:

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

dataGridViewComboBoxColumn.DataPropertyName = "License"; // not LicenseID
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:

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

我自己找到了答案。不久前我也遇到了同样的问题,并在我挖掘的一些旧代码中找到了解决方案。解决方案是在combobox中向我想要数据绑定到的对象添加一个Self属性(在上面的示例中,它将是License类),并将该属性用作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的属性“弄乱”业务类,但这要好得多(对程序员来说不那么混乱)而不是在产品类IMO中同时拥有对License的引用和LicenseId属性。此外,它使UI代码更加简单,因为无需手动获取和设置值—只需数据绑定即可