0

我在 DataGridView 中添加了一个 ComboBox

DBAccess dba = new DBAccess();
DataTable dt = dba.spGetASTMTable(); // Getting Data from DataBase for Grid
DataTable dtOrders = dba.spGetOrdersList(); / Getting Data from DataBase for ComboBox
// Create ComboBox
var cboDbTableColumn = new DataGridViewComboBoxColumn();
cboDbTableColumn.DataSource = dtOrders;
cboDbTableColumn.DataPropertyName = "OrdersID";
cboDbTableColumn.DisplayMember = "Orders";
cboDbTableColumn.HeaderText = "DbTableColumn";

gvASTMOrderMessage.Columns.Add(cboDbTableColumn);

gvASTMOrderMessage.DataSource = dt;

然后我运行我的应用程序并更改几个 ComboBoxes。我单击“保存”按钮,我想获取包含所有 DataGridView 数据的 DataTable。据我了解,由于我的 ComboBox 在 DataSource 的一部分上,因此我需要遍历整个 Grid 并将 ComboBox 的值手动添加到我的 DataTable 中。我正在尝试在这里执行此步骤:

private void btnSave_Click(object sender, EventArgs e)
{
     DataTable data = (DataTable)(gvASTMOrderMessage.DataSource);
     data.Columns.Add("DbTableColumn");
     for (int i = 0; i < gvASTMOrderMessage.Rows.Count; i++)
     {
         data.Rows[i]["DbTableColumn"] = Convert.ToString((gvASTMOrderMessage.Rows[i].Cells[0] as DataGridViewComboBoxCell).FormattedValue.ToString());
     }
} 

但这不起作用。我试图得到

gvASTMOrderMessage.Rows[i].Cells[0].FormattedValue.ToString()
gvASTMOrderMessage.Rows[i].Cells[0].Value.ToString()
gvASTMOrderMessage.Rows[i].Cells[0].EditedFormattedValue.ToString()

但这些都不起作用......

请帮助,如何从我的 DataGridView 获取每个组合框的所有值并将它们添加到 DataTable?

4

3 回答 3

1

DataSource并且DataGridView是两个不同的对象,它们以某种方式协调。但是这种协调并不完美,实际上很容易引发问题(从 中删除元素并从 中DataSource访问这些索引DataGridView)。这就是为什么,我总是喜欢同时影响两个对象(DataSourceDataGridView)。

在任何情况下,请记住,您在 中执行的很多更改DataGridView(例如,添加/删除列)不会自动反映在 中DataSource(尽管它可以反过来发生)。在您的特定情况下,这种行为更有意义,因为将DataGridViewComboBoxColumn类型列自动包含到 a DataSource(也许是 a DataTable,也许是其他对象)中几乎是不可能的(许多替代方案,客观上没有一个比其他更好)。

您应该想出一种方法来使组合框适合您的组合框DataTable(例如:在给定列中填充与组合框中的项目一样多的行并以某种方式“标记”该列)并在以下情况下实现执行相应更新操作的代码必需的。

于 2013-11-02T18:19:07.707 回答
0

也许我不明白,但请看以下代码:我添加了额外的“ComboID”列,在您在网格视图中选择项目并单击“保存”按钮后,数据表将包含组合中的 ID。

    private void Form1_Load(object sender, EventArgs e)
    {
        var dt = new DataTable();
        dt.Columns.Add("Id");
        dt.Columns.Add("Value");
        dt.Columns.Add("ComboID");

        var drow = dt.NewRow();
        drow[0] = 10;
        drow[1] = "abc";
        dt.Rows.Add(drow);

        drow = dt.NewRow();
        drow[0] = 20;
        drow[1] = "xy";
        dt.Rows.Add(drow);

        dataGridView1.AutoGenerateColumns = false;
        dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { DataPropertyName = "Id" });
        dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { DataPropertyName = "Value" });

        var dtOrders = new DataTable();
        dtOrders.Columns.Add("OrdersID");
        dtOrders.Columns.Add("Orders");

        drow = dtOrders.NewRow();
        drow[0] = 1;
        drow[1] = "Order1";
        dtOrders.Rows.Add(drow);

        drow = dtOrders.NewRow();
        drow[0] = 2;
        drow[1] = "Order2";
        dtOrders.Rows.Add(drow);

        var combo = new DataGridViewComboBoxColumn();
        combo.DataSource = dtOrders;
        combo.DataPropertyName = "ComboID";
        combo.ValueMember = "OrdersID";
        combo.DisplayMember = "Orders";
        dataGridView1.Columns.Add(combo);

        dataGridView1.DataSource = dt;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var dt = dataGridView1.DataSource as DataTable;
    }
于 2013-11-02T18:59:04.317 回答
0

嗯,你应该检查

DataTable data = (DataTable)(gvASTMOrderMessage.DataSource);

检查数据表是否为空(我的是)。其余代码似乎没问题,也检查一下

data.Rows[i]["DbTableColumn"] = Convert.ToString((gvASTMOrderMessage.Rows[i].Cells[0] as DataGridViewComboBoxCell).FormattedValue.ToString()); }

我会做类似的事情

DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)dataGridView1.Rows[i].Cells[0];
                data.Rows[i]["DbTableColumn"] = cell.FormattedValue.ToString());

这是一个更具可读性的版本。

希望这可以帮助!

于 2013-11-02T18:52:45.903 回答