私はこの問題を後方に見ているかもしれませんが、それでもなお興味があります。 DataTable
に現在表示されているものからDataGridView
を作成する方法はありますか?
明確にするために、このDataTable data = (DataTable)(dgvMyMembers.DataSource);
を実行できることを知っていますが、これには非表示の列が含まれます。表示された列のみから構築したいと思います。
それが理にかなっていることを願っています。
それで、私はそれが最良のように思われたので、いくつかの答えの組み合わせを試しました。以下は私がやろうとしていることです。基本的に、DataSourceからDataTableを作成し、列が表示されているかどうかに基づいて逆方向に作業しています。ただし、列を削除した後、Collection was modified; enumeration operation may not execute
foreach
の次の反復で。
私はそうではないので混乱していますtryingDataGridView
のみを変更し、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 data = (DataTable)(dgvMyMembers.DataSource);
そして使用する
data.Columns.Remove(...);
私はそれが最速の方法だと思います。これにより、データソーステーブルが変更されます。必要ない場合は、テーブルのコピーが必要です。 DataGridView.DataSource
は、必ずしもDataTable
タイプではありません。
私はあなたが望むことをするフレームワークによって提供されるもの(あなたが避けたいものを超えて)を知りませんが、(あなたが知っていると思うように)自分で簡単なものを作るのはかなり簡単です:
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;
}
最高のソリューションの一つはそれを楽しんだ;)
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; }
}
最初にdatagridviewのデータをリストに変換してから、リストを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;
}