Comment construire un DataTable à partir d’un DataGridView?

Il se peut que je regarde ce problème à l’envers, mais je suis néanmoins curieux. Est-il possible de construire un DataTable partir de ce qui est actuellement affiché dans le DataGridView ?

Pour être clair, je sais que vous pouvez faire cela DataTable data = (DataTable)(dgvMyMembers.DataSource); Cependant, cela inclut les colonnes cachées. Je voudrais le construire à partir des colonnes affichées uniquement.

J’espère que cela a du sens.


Alors, j’ai fini par essayer de combiner plusieurs réponses, ce qui me semblait préférable. Ci-dessous est ce que j’essaye. Fondamentalement, je crée le DataTable à partir de la source de données, puis je travaille en arrière si une colonne est visible ou non. Cependant, après avoir supprimé une colonne, une Collection was modified; enumeration operation may not execute Collection was modified; enumeration operation may not execute à la prochaine itération de foreach .

Je suis confus car je n’essaie pas de modifier le DataGridView , mais seulement le DataTable alors quoi de neuf?

 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; } 

Bien tu peux faire

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

et ensuite utiliser

 data.Columns.Remove(...); 

Je pense que c’est le moyen le plus rapide. Cela modifiera la table de source de données. Si vous ne le souhaitez pas, une copie de la table est requirejse. Sachez également que DataGridView.DataSource n’est pas nécessairement du type DataTable .

Je ne sais rien du cadre fourni (au-delà de ce que vous voulez éviter) qui ferait ce que vous voulez, mais (comme vous le savez sans doute, il serait assez facile de créer quelque chose de simple vous-même:

 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; } 

une de la meilleure solution a apprécié;)

  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 == ssortingng.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; } } 

Convertissez d’abord les données de datagridview en liste, puis convertissez List en DataTable

  public static DataTable ToDataTable( this List 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 objs = new List(); objs.AddRange ( ps.Select ( p => p.GetValue ( l , null ) ) ); dt.Rows.Add ( objs.ToArray ( ) ); } ); return dt; }