みなさんこんにちは!ひろぽんです!!
つい先日後輩にDataGridViewでDataTableを取得するのってどうすればいいんですか??と聞かれまして、ん?普通にDatasourceからとればよくない?と思ったものです。
ですが、おそらくC#初心者の方はDataGridViewにDataTableをどのように反映させるのか?
また表示されているデータをDataTableに変換して取得するにはどうすれば良いのか?
という点で悩んでしまう方も多いのではないでしょうか?
ということで、今回は「DataGridViewにDataTable反映したり変換して取得したりする」と題しDataGridViewとDataTableの扱いについていろいろ書いていこうかと思います。
[s_ad]
まずは簡単にFormを作ります
Formロード時には左にデータを表示するようにします。
その後真ん中のボタンを押せば右のDataGridViewに左のデータが移るようにする感じでつくりました。
DataGridViewにDataTableを反映させるには?
では次にDataGridViewにDataTableを反映させていきましょう
まずはDataTableを定義します。
DataTableの定義
IDと氏名と年齢と住所という列が存在するテーブルを定義します。
private DataTable getDataTable()
{
var dt = new DataTable();
var idCol = dt.Columns.Add("ID");
var nameCol = dt.Columns.Add("氏名");
var ageCol = dt.Columns.Add("年齢");
var addressCol = dt.Columns.Add("住所");
var newRow = dt.NewRow();
newRow.SetField(idCol,1);
newRow.SetField(nameCol, "鈴木 おさむ");
newRow.SetField(ageCol, 22);
newRow.SetField(addressCol, "東京都世田谷区");
dt.Rows.Add(newRow);
var newRow2 = dt.NewRow();
newRow2.SetField(idCol, 2);
newRow2.SetField(nameCol, "高橋 つよし");
newRow2.SetField(ageCol, 25);
newRow2.SetField(addressCol, "東京都葛飾区");
dt.Rows.Add(newRow2);
return dt;
}
DataGridViewのDataSourceに反映させる
反映させるのは1行で出来ます。
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = getDataTable();
}
これで実行するとこんな感じになります。
いい感じにデータが入りました!
余談1:列名を変更したいならColumnNameのプロパティを触る
DataSourceにDataTableを反映させた後列名を任意の文字列にしたいなら、DataGridViewColumnのHeaderTextプロパティを設定すれば自由に列名は触れます。
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = getDataTable();
// 列名を自由に変更する。
var col = dataGridView1.Columns["ID"];
col.HeaderText = "コード";
}
これで実行するとこんな感じ!
余談2:CustomClassもDataSourceにできます
でもう一つ余談。
DataGridViewのDataSouceには自身で作ったCustomClassも設定できます。
例えばこんなクラスを用意して
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public User(int id, string name, int age, string address)
{
ID = id;
Name = name;
Age = age;
Address = address;
}
}
こんな感じでIEnumerableのUserを返すようにしておいて
private IEnumerable<User> GetUsers()
{
var user1 = new User(1, "鈴木 おさむ",22, "東京都世田谷区");
var user2 = new User(2, "高橋 つよし",25, "東京都葛飾区");
return new List<User>()
{
user1,user2
};
}
これをdatasourceに反映させると。
private void Form1_Load(object sender, EventArgs e)
{
//dataGridView1.DataSource = getDataTable();
//// 列名を自由に変更する。
//var col = dataGridView1.Columns["ID"];
//col.HeaderText = "コード";
dataGridView1.DataSource = GetUsers().ToList();
}
こんな感じでデータが入っています。
[s_ad]
DataGridViewをDataTableに変換して取得するには?
これは数行で取得できます。
private void button1_Click(object sender, EventArgs e)
{
var data = (DataTable)dataGridView1.DataSource;
dataGridView2.DataSource = data;
}
これを実行するとこんな感じになります。
真ん中のボタンを押すと!
右に同じデータが表示されました!
仮に左のデータを操作して右に投げると!
このままだと同じインスタンスになってるので、左右で同じ動きになってしまう。
この現象は同じDatatableを参照しているため。
ボタンを押したタイミングで、DataGridView1で触ったデータとDataGridView2に表示されているデータは同じインスタンスを参照するようになっている。
そのために上記のような現象が起こる。
これを回避するために下記のようにDataTableをコピーして別インスタンスをDataGridView2に反映させる。
private void button1_Click(object sender, EventArgs e)
{
var data = (DataTable)dataGridView1.DataSource;
var newDt = data.Copy();
dataGridView2.DataSource = newDt;
}
こうするとさっきのような事は起こらない。
今回のソースコードはGithubに公開しています。
今回サンプルで紹介したコードはGithubに「DataGridViewWithDataTable」というフォルダ名で公開しています!
Githubのリポジトリについては下記を参照ください!
コメント