【C#】DataGridViewにDataTable反映したり変換して取得したりする

この記事は約 6 分で読めます。

みなさんこんにちは!ひろぽんです!!

つい先日後輩にDataGridViewでDataTableを取得するのってどうすればいいんですか??と聞かれまして、ん?普通にDatasourceからとればよくない?と思ったものです。

ですが、おそらくC#初心者の方はDataGridViewにDataTableをどのように反映させるのか?

また表示されているデータをDataTableに変換して取得するにはどうすれば良いのか?

という点で悩んでしまう方も多いのではないでしょうか?

ということで、今回は「DataGridViewにDataTable反映したり変換して取得したりする」と題しDataGridViewとDataTableの扱いについていろいろ書いていこうかと思います。

まずは簡単に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();
        }

こんな感じでデータが入っています。

DataGridViewをDataTableに変換して取得するには?

これは数行で取得できます。

        private void button1_Click(object sender, EventArgs e)
        {
            var data = (DataTable)dataGridView1.DataSource;
            dataGridView2.DataSource = data;
        }

これを実行するとこんな感じになります。

真ん中のボタンを押すと!

右に同じデータが表示されました!

仮に左のデータを操作して右に投げると!

3行目にデータを追加した
おなじデータが表示されている。

このままだと同じインスタンスになってるので、左右で同じ動きになってしまう。

この状態で鈴木たかひろを鈴木よしろうにする
すると両方とも同時に変わって同期的な動きになってしまう

この現象は同じ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のリポジトリについては下記を参照ください!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA