【问题标题】:Bind different entries to DataGridViewComboBoxCell from a data source将不同条目从数据源绑定到 DataGridViewComboBoxCell
【发布时间】:2010-03-19 16:11:47
【问题描述】:

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

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; }
    }

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    今天早上过来,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; }
    }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多