【问题标题】:How to build a DataTable from a DataGridView?如何从 DataGridView 构建 DataTable?
【发布时间】:2011-09-11 19:35:29
【问题描述】:

我可能会倒着看这个问题,但我仍然很好奇。有没有办法从DataGridView 中当前显示的内容构建DataTable

需要明确的是,我知道您可以这样做DataTable data = (DataTable)(dgvMyMembers.DataSource);,但其中包括隐藏列。我只想从显示的列中构建它。

希望这是有道理的。


所以我最终尝试了几个答案的组合,因为这似乎是最好的。下面是我正在尝试的。基本上我是从数据源创建数据表,然后根据列是否可见向后工作。但是,在它删除一列之后,我在 foreach 的下一次迭代中得到一个 Collection was modified; enumeration operation may not execute

我很困惑,因为我没有尝试修改DataGridView,只有DataTable,所以怎么了?

DataTable data = GetDataTableFromDGV(dgvMyMembers);


    private DataTable GetDataTableFromDGV(DataGridView dgv)
    {
        var dt = ((DataTable)dgv.DataSource).Copy();
        foreach (DataGridViewColumn column in dgv.Columns)
        {
            if (!column.Visible)
            {
                dt.Columns.Remove(column.Name);
            }
        }
        return dt;
    }

【问题讨论】:

  • 您收到错误是因为 DataTable 已绑定到 DGV;当您从 DT 中删除列时,DGV 中的绑定列也将被删除。在删除列之前复制 DT,将您的分配更改为 dt 为:var dt = ((DataTable)dgv.DataSource).Copy();

标签: c# .net datagridview datatable


【解决方案1】:

嗯,你可以的

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

然后使用

data.Columns.Remove(...);

我认为这是最快的方法。这将修改数据源表,如果您不想要它,则需要表的副本。还要注意DataGridView.DataSource 不一定是DataTable 类型。

【讨论】:

  • 不错的答案!我欣赏简洁的代码。我还感谢您使用 Gadget 作为您的头像。老派的胜利!
  • 我不知道该给谁打勾。我的解决方案最终成为这个答案和 Jay Riggs 答案的相等组合。
  • 仅当数据源不为空时才有效
【解决方案2】:

我不知道框架提供的任何东西(超出你想要避免的东西)会做你想做的事,但是(我怀疑你知道)自己创建一些简单的东西很容易:

private DataTable GetDataTableFromDGV(DataGridView dgv) {
    var dt = new DataTable();
    foreach (DataGridViewColumn column in dgv.Columns) {
        if (column.Visible) {
            // You could potentially name the column based on the DGV column name (beware of dupes)
            // or assign a type based on the data type of the data bound to this DGV column.
            dt.Columns.Add();
        }
    }

    object[] cellValues = new object[dgv.Columns.Count];
    foreach (DataGridViewRow row in dgv.Rows) {
        for (int i = 0; i < row.Cells.Count; i++) {
            cellValues[i] = row.Cells[i].Value;
        }
        dt.Rows.Add(cellValues);
    }

    return dt;
}

【讨论】:

    【解决方案3】:

    享受它的最佳解决方案之一;)

      public DataTable GetContentAsDataTable(bool IgnoreHideColumns=false)
            {
                try
                {
                    if (dgv.ColumnCount == 0) return null;
                    DataTable dtSource = new DataTable();
                    foreach (DataGridViewColumn col in dgv.Columns)
                    {
                        if (IgnoreHideColumns & !col.Visible) continue;
                        if (col.Name == string.Empty) continue;
                        dtSource.Columns.Add(col.Name, col.ValueType);
                        dtSource.Columns[col.Name].Caption = col.HeaderText;
                    }
                    if (dtSource.Columns.Count == 0) return null;
                    foreach (DataGridViewRow row in dgv.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; }
            }
    

    【讨论】:

    • 异常发生在 dtSource.Columns.Add(col.Name, col.ValueType);命令 if ValueType == null
    【解决方案4】:

    先把你datagridview的数据转成List,再把List转成DataTable

            public static DataTable ToDataTable<T>( this List<T> list) where T : class {
            Type type = typeof(T);
            var ps = type.GetProperties ( );
            var cols = from p in ps
                       select new DataColumn ( p.Name , p.PropertyType );
    
            DataTable dt = new DataTable();
            dt.Columns.AddRange(cols.ToArray());
    
            list.ForEach ( (l) => {
                List<object> objs = new List<object>();
                objs.AddRange ( ps.Select ( p => p.GetValue ( l , null ) ) );
                dt.Rows.Add ( objs.ToArray ( ) );
            } );
    
            return dt;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-16
      • 1970-01-01
      • 2017-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多