Привязка данных столбца комбинированного списка к сетке данных для каждой строки (не для всего столбца) - PullRequest
4 голосов
/ 06 мая 2011

Есть несколько сообщений об этом, но после нескольких часов поиска я все еще не могу найти то, что мне нужно.

Ответ в следующем посте почти дает мне то, что я хочу: Combobox дляВнешний ключ в DataGridView

Вопрос 1:

Если исходить из того примера, когда у продукта много лицензий, все сопоставления моей базы данных являются отношениями "многие к одному".Это означает, что мой класс License содержит ссылку на класс Product.Класс License не имеет свойства для ProductId, поскольку его можно получить с помощью ссылки на Product.Я не хочу портить класс License и ссылкой на Product, и на свойство ProductId, чтобы упростить привязку в пользовательском интерфейсе.

Из-за этого я не могу установить DataPropertyName вПоле идентификатора.Это должно быть имя ссылки на класс, например, так:

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

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

**** Обновление **** Я смог заставить это работать частично без создания свойства ProductId, указав Product.Id какDataPropertyName, например, так:

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 Ответ

4 голосов
/ 16 мая 2011

Я нашел ответ сам. У меня была такая же проблема некоторое время назад, и я нашел решение в каком-то старом коде, который я выкопал. Решением было добавить свойство 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!
}

Класс License теперь выглядит так:

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

    public ILicense Self
    {
        get { return this; }
    }

    // ... more properties
}

Конечно, мне пришлось "испортить" бизнес-классы с помощью свойства Self, но это гораздо лучше (менее запутанно для программиста), чем указывать ссылку на свойство License и LicenseId в классе IMO Product. Кроме того, он значительно упрощает код пользовательского интерфейса, так как нет необходимости вручную получать и устанавливать значения - достаточно просто связать данные и все готово.

...