Привязка данных столбца комбинированного списка к сетке данных для каждой строки (не для всего столбца)
Есть несколько сообщений об этом, но после нескольких часов поиска я все еще не могу найти то, что мне нужно.
Ответ в следующем посте почти дает мне то, что я хочу: 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 ответ
Я нашел ответ сам. У меня была такая же проблема некоторое время назад, и я нашел решение в каком-то старом коде, который я выкопал. Решением было добавить свойство 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 в классе Product IMO. Кроме того, он значительно упрощает код пользовательского интерфейса, так как нет необходимости вручную получать и устанавливать значения - достаточно просто связать данные и все готово.