2010-03-19 43 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;