从DataGridView获取DataTable

10

我有一个CRUD表单,可以管理许多表中的任何数据。如果表中有外键,CRUD会找到相应列的表和列名。因此,在DataGridView中可以显示列为复选框、文本框或组合框。

在填充数据之前,我完成了所有这些操作,所以我不能使用以下内容:

dataGridView1.DataSource = dtCurrent;

我需要类似这样的东西:

dtCurrent = dataGridView1.DataSource;

但只需提供一个空值

我尝试使用扩展方法来操作DataGridView:

public static DataTable ToDataTable(this DataGridView dataGridView, string tableName)
{

    DataGridView dgv = dataGridView;
    DataTable table = new DataTable(tableName);

    // Crea las columnas 
    for (int iCol = 0; iCol < dgv.Columns.Count; iCol++)
    {
        table.Columns.Add(dgv.Columns[iCol].Name);
    }

    /**
      * THIS DOES NOT WORK
      */
    // Agrega las filas 
    /*for (int i = 0; i < dgv.Rows.Count; i++)
    {
        // Obtiene el DataBound de la fila y copia los valores de la fila 
        DataRowView boundRow = (DataRowView)dgv.Rows[i].DataBoundItem;
        var cells = new object[boundRow.Row.ItemArray.Length];
        for (int iCol = 0; iCol < boundRow.Row.ItemArray.Length; iCol++)
        {
            cells[iCol] = boundRow.Row.ItemArray[iCol];
        }

        // Agrega la fila clonada                 
        table.Rows.Add(cells);
    }*/

    /* THIS WORKS BUT... */
    foreach (DataGridViewRow row in dgv.Rows)
    {

        DataRow datarw = table.NewRow();

        for (int iCol = 0; iCol < dgv.Columns.Count; iCol++)
        {
            datarw[iCol] = row.Cells[iCol].Value;
        }

        table.Rows.Add(datarw);
    }

    return table;
} 

我使用:

dtCurrent = dataGridView1.ToDataTable(dtCurrent.TableName);

代码无法运行的情况:

int affectedUpdates = dAdapter.Update(dtCurrent);

我收到一个关于重复值的异常(从西班牙语翻译过来):

由于更改会在索引、主键或关系中创建重复值,所以对表请求的更改未成功。更改包含重复数据的字段或字段中的数据,删除索引或重新定义索引以允许重复条目,然后重试。

我只需要使用DataTable更新DataGridView中的更改。

5个回答

8
如果您需要引用实际的DataTable源代码,请尝试以下方法:
 ((DataRowView)DataGridView1.Rows[0].DataBoundItem).DataView.Table 

不要忘记处理错误。


((DataRowView)DataGridView1.Rows[0].DataBoundItem).DataView 的值是之前我放入的, 但是 ((DataRowView)DataGridView1.Rows[0].DataBoundItem).DataView.Table 没有任何值。 - Sophie
((DataRowView)DataGridView1.Rows[0].DataBoundItem).DataView中包含了我之前输入的值。 但是((DataRowView)DataGridView1.Rows[0].DataBoundItem).DataView.Table中没有任何值。 - undefined

8

或者,这可能有助于将DataGridView转换为DataTable。

Dim dt As New DataTable
dt = (DirectCast(DataGridView1.DataSource, DataTable))

将DataTable直接转换为DataGridView可以得到最终结果。

6
类似于上面的代码 DataTable dataTable = (DataTable) dataGridView1.DataSource; 对我有用。 另请参见:https://dev59.com/Vm015IYBdhLWcg3w9gjh - surfmuggle
在C#中,var dt = new DataTable(); dt = (DataTable)DataGridView1.DataSource; - Md Ashraful Islam
这个解决方案给我报错了,错误信息是“无法将类型为Dataview的对象转换为类型DataTable”。 - Sophie

2
我写了类似这样的东西:
private DataTable GetDataGridViewAsDataTable(DataGridView _DataGridView) 
{
    try {
        if (_DataGridView.ColumnCount == 0) return null;
        DataTable dtSource = new DataTable();
        //////create columns
        foreach(DataGridViewColumn col in _DataGridView.Columns) {
            if (col.ValueType == null) dtSource.Columns.Add(col.Name, typeof(string));
            else dtSource.Columns.Add(col.Name, col.ValueType);
            dtSource.Columns[col.Name].Caption = col.HeaderText;
        }
        ///////insert row data
        foreach(DataGridViewRow row in _DataGridView.Rows) {
            DataRow drNewRow = dtSource.NewRow();
            foreach(DataColumn col in dtSource.Columns) {
                drNewRow[col.ColumnName] = row.Cells[col.ColumnName].Value;
            }
            dtSource.Rows.Add(drNewRow);
        }
        return dtSource;
    }
    catch {
        return null;
    }
}

1
 DataTable dt = new DataTable();
    dt = ((DataTable)DataGridView1.DataSource);

来自评论区:嗨,请不要只回答源代码。尝试提供一个关于你的解决方案如何工作的好描述。请参阅:如何撰写一个好的答案?。谢谢。 - sɐunıɔןɐqɐp

-2
这个怎么样?
DataView dv = (DataView)(dataGridView1.DataSource);

dt = dv.ToTable();

适用于所有情况!


2
你不能将 DataTable 转换为 DataView。只需直接使用 DataTable dt = (DataTable)(dataGridView1.DataSource);,无需转换为 DataView。 - randomizer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接