【问题标题】:Copy ComboBox Dataset to DataGridViewComboBoxColumn将 ComboBox 数据集复制到 DataGridViewComboBoxColumn
【发布时间】:2017-02-13 17:01:27
【问题描述】:

(使用 C# Visual Studio 2015,Windows 窗体)

我有一个要在 DataGridView (DGV) 中显示的字符串列表。

DGV 中的每一行都有:

  • column[0]: 列表中的字符串值 (ColumnType: DataGridViewTextBoxColumn)
  • column[1]:空白单元格(用户将在此处输入数据)(ColumnType:DataGridViewTextBoxColumn
  • column[2]: 一个 ComboBox (ColumnType: DataGridViewComboBoxColumn)

每条记录中的每个 ComboBox 都将具有相同的项目(相同的数据集),我将这些项目从 SQL 查询中检索到我的 Access 数据库 (accdb)。

我的主要问题是我需要识别每个 ComboBox 的 ValueMemberDisplayMember,但我不知道该怎么做。我当前的代码只是尝试将 DataTable results 复制到 ComboBox 中,但出现错误:
System.ArgumentException.DataGridViewComboBoxCell value is not valid.

它对 DataGridView 中每个 ComboBox 的每个值重复。我无法弄清楚我做错了什么。

任何帮助将不胜感激。代码如下:

     DataTable results = new DataTable();

     //Identify the Connection String
     connection.ConnectionString = dbQuery.connStr;

     //SQL Statement to retrieve ComboBox Items
     string sql = @"SELECT ID, DESCRIP FROM tbl_setpoints_categories ORDER BY DESCRIP ASC";

     //Create a new ComboBox (this is for testing purposes)
     ComboBox cb = new ComboBox();

        try
        {
            connection.Open();
            OleDbCommand command = new OleDbCommand();
            command.Connection = connection;
            command.CommandText = sql;
            OleDbDataReader reader = command.ExecuteReader();

            results.Columns.Add("ID", typeof(int));
            results.Columns.Add("DESCRIP", typeof(string));
            results.Load(reader);

            //For testing purposes...
            cb.ValueMember = "ID";
            cb.DisplayMember = "DESCRIP";
            cb.DataSource = results;

            if (!reader.IsClosed)
            {
                reader.Close();
            }
        }
        finally
        {
            connection.Close();
        }


        //Loop through the list and add each into an array of objects
        //This array will be added as a DataGridView row
        foreach (string spName in spList)
        {

            //My Latest Edit, but still produces same error
            DataGridViewComboBoxCell cbCell = new DataGridViewComboBoxCell();
            cbCell.ValueMember = "ID";
            cbCell.DisplayMember = "DESCRIP";
            cbCell.DataSource = results;
            //End Latest Edit

            object[] row = new object[3];
            row[0] = spName.ToString();
            row[1] = "";
            row[2] = cbCell;  //From Latest Edit (was: results)
            dataGridView1.Rows.Add(row);
        }

编辑:我刚刚检查了我的查询是否通过添加以下行来提取记录:
MessageBox.Show(results.Rows.Count.ToString());
我收到了正确数量的记录

【问题讨论】:

标签: c# datagridview combobox


【解决方案1】:

希望这可以解决问题。不幸的是,DataGridViewComboBoxColumn 不是ComboBoxcontrols 的列。所以下面的行不能用作DataGridView 列。

ComboBox cb = new ComboBox();
cb.ValueMember = "ID";
cb.DisplayMember = "DESCRIP";
cb.DataSource = results;

DataGridView 有一个DataGridViewComboBoxColumn,不幸的是,它比普通的ComboBox 更难实现。因此,为了帮助形象化,我画了一张图来展示我所描述的内容。

您可以在上面看到下面代码的输出。我使用按钮单击放置断点以显示两个DataTablesDataGridViewComboBoxColumn DataSource 是具有不同“设置点类型”的DataTable,显示在右侧,显示“Id”和“设置点类型”0-14。这些是DataGridViewComboBoxColumn 用作DataSource. 的项目

方便的是,一旦您为此列设置了DataSource,您就不必使用每个新的/现有的单元格来更新它。该列将自动构建ComboBoxCells。当您使用所有数据为主要DataGridView 创建DataTable 时,您会假设组合框列所在的单元格需要具有所有值。但是这些值将只是一个与组合框中的项目之一匹配的单个字符串(希望如此)。因此DataGridViewDataTable(不是DataGridView 列)需要将此列设为字符串(不是组合框),因为它只能包含来自不同“设置点类型”类型的一个值。方便的方面是,即使它是一个字符串而不是组合框,如果它与组合框中的现有项目匹配,那么它将显示该项目。

下面是用于上图的代码。

首先将DataGridView 列设置为两个文本列,然后最后一列是DataGridViewComboBoxColumnGetComboColumn 方法返回一个DatGridViewComboBoxColumn,其中包含组合框的不同项目。这里相关的属性是DataPropertyNameDisplayMemeberValueMember,它们从DataSource 中确定要使用哪些列。下面是向DataTable 添加文本列的方法。

最后,我们得到了DataTableDataGridView 以及一些用于测试的测试数据。希望这会有所帮助。

DataTable allData;
DataTable comboTable;

public Form1() {
  InitializeComponent();
}

//-------------------------------------------------------------------------
private void Form1_Load(object sender, EventArgs e) {
  SetDGVColumns();
  allData = GetAllData();
  dataGridView1.DataSource = allData;
}

private DataTable GetAllData() {
  DataTable data = new DataTable();
  data.Columns.Add("Set Point Name", typeof(string));
  data.Columns.Add("Description", typeof(string));
  data.Columns.Add("Set Point Type", typeof(string));  // <-- NOTE: this is a string- not a combo box

  data.Rows.Add("nai_m2_no2", "Description 0", "Set Point Type 4");
  data.Rows.Add("nao_enth_no3", "Description 1", "Set Point Type 13");
  data.Rows.Add("nai_m2_no4", "Description 2", "Set Point Type 4");
  data.Rows.Add("nai_m2_no5", "Description 3", "Set Point Type 11");
  data.Rows.Add("nai_m2_no6", "Description 4", "Set Point Type 3");
  data.Rows.Add("nai_m2_no7", "Description 5", "Set Point Type 2");
  return data;
}

//-------------------------------------------------------------------------
private void SetDGVColumns() {
  AddTextCol("Set Point Name");
  AddTextCol("Description");
  dataGridView1.Columns.Add(GetComboColumn()); // <-- THIS DataGridView Column needs to be a combo box column
}

//-------------------------------------------------------------------------
private DataGridViewComboBoxColumn GetComboColumn() {
  comboTable = new DataTable();
  comboTable.Columns.Add("ID", typeof(int));
  comboTable.Columns.Add("Set Point Type", typeof(string));
  for (int i = 0; i < 15; i++) {
    comboTable.Rows.Add(i, "Set Point Type " + i);
  }
  // we now have a data table to use as a data source for the DataGridViewComboBoxColumn
  // make a DataGridViewComboBoxColumn and set it properties
  DataGridViewComboBoxColumn typeCol = new DataGridViewComboBoxColumn();
  typeCol.Width = 150;
  typeCol.DataPropertyName = "Set Point Type";  //<-- needs to match the DataTable column name you want to display - in this case 'Set Point Type'
  typeCol.HeaderText = "Set Point Type";
  typeCol.ValueMember = "Set Point Type";
  typeCol.DisplayMember = "Set Point Type";
  typeCol.Name = "Set Point Type";
  typeCol.DataSource = comboTable;
  return typeCol;
}

//-------------------------------------------------------------------------
private void AddTextCol(string colInfo) {
  DataGridViewTextBoxColumn TextCol = new DataGridViewTextBoxColumn();
  TextCol.DataPropertyName = colInfo;
  TextCol.HeaderText = colInfo;
  TextCol.Name = colInfo;
  dataGridView1.Columns.Add(TextCol);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 2011-09-19
    • 2013-03-24
    • 1970-01-01
    • 2015-08-23
    • 2011-12-01
    • 1970-01-01
    相关资源
    最近更新 更多