从数据源将不同的条目绑定到DataGridViewComboBoxCell

我想要在DataGridView中显示以下数据:

DataEntry[] data = new[]{ new DataEntry(){Name = "A", Entries = new []{ "1", "2"}}, new DataEntry(){Name = "B", Entries = new []{ "1", "2", "3"}}}; 

“Name”将是一个简单的TextBox字段,“Entries”是一个ComboBox,其中可供选择的项目是列表中的元素。

所以在这个例子中会有2行(下面是datagridview的样子):

  Name Entries Row1 : A  Row1 : B  

我的问题是,如何绑定这些数据?! 我查看了DataPropertyName,DisplayMember和ValueMember属性……但是无法解决这个问题。

下面是代码 – 有一个注释,我需要添加神奇的几行来为Entries列设置DataSource等。

 public partial class Form1 : Form { DataEntry[] data = new[]{ new DataEntry(){Name = "A", Entries = new []{ "1", "2"}}, new DataEntry(){Name = "B", Entries = new []{ "1", "2", "3"}}}; public Form1() { InitializeComponent(); dataGridView1.AutoGenerateColumns = false; var nameCol = new DataGridViewTextBoxColumn(); nameCol.DataPropertyName = "Name"; var entriesCol = new DataGridViewComboBoxColumn(); //entriesCol. ???? = "Entries"; !! dataGridView1.Columns.AddRange(new DataGridViewColumn[] { nameCol, entriesCol }); dataGridView1.DataSource = data; } } public class DataEntry { public string Name { get; set; } public IEnumerable Entries { get; set; } } 

今天早上进来,10分钟后我就开始工作了!

谢谢你去这个MSDN论坛post

解决方案是订阅“DataBindingComplete”事件,然后遍历每一行并在每个ComboBoxCell上设置数据源。 拥有一个更优雅的解决方案会很高兴 – 但是嘿 – 它有效!

以下是我在原始问题中提交的代码示例的工作版本:

 public partial class Form1 : Form { DataEntry[] data = new[]{ new DataEntry(){Name = "A", Entries = new []{ "1", "2", "3", "4"}}, new DataEntry(){Name = "B", Entries = new []{ "1", "2", "3"}}}; string[] cols = new[] { "col1", "col2" }; public Form1() { InitializeComponent(); dataGridView1.AutoGenerateColumns = false; var nameCol = new DataGridViewTextBoxColumn(); nameCol.DataPropertyName = "Name"; var entriesCol = new DataGridViewComboBoxColumn(); entriesCol.Name = "Entries"; dataGridView1.Columns.AddRange(new DataGridViewColumn[] { nameCol, entriesCol }); dataGridView1.DataSource = data; dataGridView1.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dataGridView1_DataBindingComplete); } void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e) { for (int i = 0; i < dataGridView1.Rows.Count; i++) { DataGridViewComboBoxCell comboCell = (DataGridViewComboBoxCell)dataGridView1.Rows[i].Cells["Entries"]; DataEntry entry = dataGridView1.Rows[i].DataBoundItem as DataEntry; comboCell.DataSource = entry.Entries; comboCell.Value = entry.Entries.First(); } } } public class DataEntry { public string Name { get; set; } public IEnumerable Entries { get; set; } } 

我最近不得不这样做,并找到了一个不同的解决方案。

我使用了2个BindingSource来完成工作。 第一个用于填充Datagrid,第二个用于ComboBoxColumn并使用第一个BindingSource,因为它的DataSource引用了DataMember。

这是我们可能想要绑定的DataObject:

 class DataObject { public string Name { get; set; } public string Value { get; set; } public string [] ValueList { get; set; } } 

Designer文件看起来像:

 // dataGridView1 this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.nameDataGridViewTextBoxColumn, this.valueDataGridViewTextBoxColumn}); this.dataGridView1.DataSource = this.bindingSource1; // bindingSource1 this.bindingSource1.DataSource = typeof(SomeNamespace.DataObject); // valueListBindingSource this.valueListBindingSource.DataMember = "ValueList"; this.valueListBindingSource.DataSource = this.bindingSource1; // nameDataGridViewTextBoxColumn this.nameDataGridViewTextBoxColumn.DataPropertyName = "Name"; // valueDataGridViewTextBoxColumn this.valueDataGridViewTextBoxColumn.DataPropertyName = "Value"; this.valueDataGridViewTextBoxColumn.DataSource = this.valueListBindingSource; 

然后一个简单的表格可能看起来像:

 public Form1 () { InitializeComponent (); m_objects = new List { new DataObject { Name = "foo", ValueList = new [] { "1", "2", "3", "4" }}, new DataObject { Name = "bar", ValueList = new [] { "a", "b", "c" }} }; bindingSource1.DataSource = m_objects; } private IList m_objects;