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

时间:2010-03-19 16:11:48

标签: c# .net winforms

我想在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                    <choice of "1" or "2">
Row1 :    B                    <choice of "1" or "2" or "3">

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

下面是代码 - 注释,我需要添加神奇的几行来为条目列设置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; }
    }

2 个答案:

答案 0 :(得分: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 :(得分:1)

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

我使用了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<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;