2010-03-19 42 views
3

,我有以下的数据我想在一个DataGridView显示:绑定不同的条目的DataGridViewComboBoxCell

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

“名称”将是一个简单的文本框字段,“项”组合框,其中可供选择的项目是列表中的元素。

因此,在这个例子中会有2行(下面是在DataGridView会是什么样子):

 Name       Entries 

Row1 : A     <choice of "1" or "2"> 
Row1 : B     <choice of "1" or "2" or "3"> 

我的问题是,我怎么绑定这个数据?我已经看了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<string> Entries { get; set; } 
    } 

回答

4

来吧今天早上,在10分钟内我有它的工作!

由于去this MSDN forum 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<string> Entries { get; set; } 
} 
1

最近,我不得不这样做,发现了不同的解决方案。

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

这里是我们可能要绑定一个数据对象:

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

的设计文件看起来是这样的:

// 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<DataObject> { 
    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<DataObject> m_objects;