Как построить DataTable из DataGridView? - PullRequest
14 голосов
/ 09 июня 2011

Я вполне могу смотреть на эту проблему задом наперед, но тем не менее мне любопытно. Есть ли способ построить DataTable из того, что в данный момент отображается в DataGridView?

Чтобы было ясно, я знаю, что вы можете сделать это DataTable data = (DataTable)(dgvMyMembers.DataSource);, однако это включает скрытые столбцы. Я хотел бы построить его только из отображаемых столбцов.

Надеюсь, что это имеет смысл.


Так что в итоге я попробовал комбинацию из пары ответов, поскольку это казалось лучшим. Ниже то, что я пытаюсь. В основном я создаю DataTable из DataSource, а затем работаю в обратном направлении, основываясь на том, видим столбец или нет. Однако после удаления столбца я получаю Collection was modified; enumeration operation may not execute на следующей итерации foreach.

Я в замешательстве, поскольку я не пытаюсь изменить 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;
    }

Ответы [ 4 ]

20 голосов
/ 09 июня 2011

Ну, вы можете сделать

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

, а затем использовать

data.Columns.Remove(...);

Я думаю, что это самый быстрый способ.Это изменит таблицу источника данных, если вы этого не хотите, тогда требуется копия таблицы.Также учтите, что DataGridView.DataSource не обязательно относится к типу DataTable.

16 голосов
/ 09 июня 2011

Я не знаю ничего, что предоставляет Framework (помимо того, что вы хотите избежать), которое бы делало то, что вы хотите, но (как я подозреваю, вы знаете) было бы довольно легко создать что-то простое самостоятельно:

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;
}
6 голосов
/ 12 ноября 2012

одно из лучших решений понравилось;)

  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; }
        }
3 голосов
/ 09 июня 2011

Сначала преобразуйте данные вашей таблицы данных в Список, затем преобразуйте Список в 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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...