記事内に広告が含まれています。

DataGridView で行を追加する方法(サンプルあり)

2026年6月9日

DataGridView への行追加は、DataSource にバインドしているかどうかで方法が変わります。

バインドなしの場合は dataGridView1.Rows.Add() で直接追加できますが、バインドしている場合に同じコードを書くと実行時エラーになります。本記事では、状況別の行追加方法と、よくあるエラーの原因・対処法を C# サンプルコードとともに解説します。

バインドなし:Rows.Add() で直接追加

DataSource を設定せず、列を手動で追加している場合は Rows.Add() で直接行を追加できます。

C#

// 値を直接指定して追加(列の順番に対応)
dataGridView1.Rows.Add("値1", "値2", "値3");

列数が多い場合や、追加後にセル値を個別に設定したい場合は、行オブジェクトを先に作ってから追加する方法が読みやすいです。

C#

// 行オブジェクトを作ってから追加する
DataGridViewRow row = (DataGridViewRow)dataGridView1.Rows[0].Clone();
row.Cells[0].Value = "値1";
row.Cells[1].Value = "値2";
row.Cells[2].Value = "値3";
dataGridView1.Rows.Add(row);

注意: DataSource にデータをバインドしている状態で Rows.Add() を呼ぶと InvalidOperationException が発生します。バインドあり・なしの判断を最初に確認してください。

バインドあり(DataTable):DataTable に行を追加する

DataGridView に DataTable をバインドしている場合、行の追加は DataTable 側に対して行います。DataTable に行を追加すると、DataGridView の表示に自動的に反映されます。

C#

// DataTable に新しい行を追加する(パターン①:値を直接指定)
DataRow newRow = _dataTable.NewRow();
newRow["ID"]   = 4;
newRow["Name"] = "たろう";
newRow["Age"]  = 30;
_dataTable.Rows.Add(newRow);

列の順番が決まっていて簡潔に書きたい場合は、値を直接渡す書き方も使えます。

C#

// DataTable に新しい行を追加する(パターン②:列順に値を指定)
_dataTable.Rows.Add(4, "たろう", 30);

ポイント: _dataTable はフィールド変数として保持しておく必要があります。Form_Load 内でローカル変数に DataTable を作って DataSource に設定するだけでは、後から行を追加できません。

バインドあり(BindingList):BindingList に行を追加する

BindingList<T> をバインドしている場合は、リストにオブジェクトを追加するだけで DataGridView に反映されます。

C#

// BindingList にオブジェクトを追加する
_products.Add(new Product { ID = 4, Name = "ぶどう", Price = 500 });

BindingList<T> は変更通知を持っているため、Add() を呼ぶだけで自動的に画面が更新されます。DataTable と違い、型安全に扱えるのが利点です。

よくあるエラーと原因

エラー①:InvalidOperationException(バインド中に Rows.Add を呼ぶ)

System.InvalidOperationException:
'DataSource が設定されている場合、行をプログラムで DataGridView に追加することはできません。'

原因: DataSource にバインドした状態で dataGridView1.Rows.Add() を呼んでいます。

対処: DataTable や BindingList など、バインドしているデータソース側に行を追加してください。

エラー②:行を追加したのに画面に反映されない

原因: DataTable をローカル変数で作成してバインドしたため、後からアクセスできていません。

C#

// NG:Form_Load 内のローカル変数に DataTable を作成している
private void Form1_Load(object sender, EventArgs e)
{
    DataTable dt = new DataTable(); // ← ローカル変数
    dt.Columns.Add("Name", typeof(string));
    dataGridView1.DataSource = dt;
}

private void btnAdd_Click(object sender, EventArgs e)
{
    // dt にアクセスできないため、行を追加できない
}

対処: DataTable をフィールド変数として宣言して保持してください。

C#

// OK:フィールド変数として保持する
private DataTable _dataTable = new DataTable();

private void Form1_Load(object sender, EventArgs e)
{
    _dataTable.Columns.Add("Name", typeof(string));
    dataGridView1.DataSource = _dataTable;
}

private void btnAdd_Click(object sender, EventArgs e)
{
    _dataTable.Rows.Add("たろう"); // フィールド変数なのでアクセス可能
}

エラー③:追加した行が最下行の「*」行の後に入らない

原因: AllowUserToAddRows = true(デフォルト)の状態では、「*」の新規追加行が常に最下行に表示されます。これは仕様通りの動作です。

対処: プログラムから行を追加する用途で新規追加行が不要な場合は、AllowUserToAddRows = false を設定してください。

C#

dataGridView1.AllowUserToAddRows = false;

新規追加行の詳細な制御については、「DataGridView:新規追加行の表示・非表示制御と注意点」を参照してください。

サンプルコード

3つの行追加パターンをタブ切り替えで確認できるサンプルアプリです。「バインドなし」「DataTable バインド」「BindingList バインド」それぞれのボタンで行を追加し、動作の違いを確認できます。

C#

using System.ComponentModel;

namespace DataGridView_AddRow
{
    public partial class Form1 : Form
    {
        // ── フィールド変数 ──────────────────────────────
        // DataTable バインド用
        private DataTable _dataTable = new DataTable();

        // BindingList バインド用
        private BindingList<Product> _products = new BindingList<Product>();

        // ── コンストラクタ ──────────────────────────────
        public Form1()
        {
            InitializeComponent();

            // タブ①:バインドなし
            SetupNoBindTab();

            // タブ②:DataTable バインド
            SetupDataTableTab();

            // タブ③:BindingList バインド
            SetupBindingListTab();
        }

        // ════════════════════════════════════════════════
        // タブ①:バインドなし(Rows.Add で直接追加)
        // ════════════════════════════════════════════════
        private void SetupNoBindTab()
        {
            // 列を手動で追加
            dataGridViewNoBind.Columns.Add("ColID",   "ID");
            dataGridViewNoBind.Columns.Add("ColName", "名前");
            dataGridViewNoBind.Columns.Add("ColAge",  "年齢");
            dataGridViewNoBind.AllowUserToAddRows = false;

            // ボタンクリックで行を追加
            btnAddNoBind.Click += (s, e) =>
            {
                int nextId = dataGridViewNoBind.Rows.Count + 1;
                dataGridViewNoBind.Rows.Add(nextId, $"ユーザー{nextId}", 20 + nextId);
            };
        }

        // ════════════════════════════════════════════════
        // タブ②:DataTable バインド
        // ════════════════════════════════════════════════
        private void SetupDataTableTab()
        {
            // DataTable の列定義
            _dataTable.Columns.Add("ID",   typeof(int));
            _dataTable.Columns.Add("Name", typeof(string));
            _dataTable.Columns.Add("Age",  typeof(int));

            // 初期データ
            _dataTable.Rows.Add(1, "じゅんや", 23);
            _dataTable.Rows.Add(2, "きょうこ", 25);
            _dataTable.Rows.Add(3, "えみ",   24);

            // DataGridView にバインド
            dataGridViewDT.DataSource        = _dataTable;
            dataGridViewDT.AllowUserToAddRows = false;

            // ボタンクリックで DataTable に行追加 → DataGridView に自動反映
            btnAddDT.Click += (s, e) =>
            {
                int nextId = _dataTable.Rows.Count + 1;
                DataRow newRow = _dataTable.NewRow();
                newRow["ID"]   = nextId;
                newRow["Name"] = $"ユーザー{nextId}";
                newRow["Age"]  = 20 + nextId;
                _dataTable.Rows.Add(newRow);
            };
        }

        // ════════════════════════════════════════════════
        // タブ③:BindingList バインド
        // ════════════════════════════════════════════════
        private void SetupBindingListTab()
        {
            // 初期データ
            _products.Add(new Product { ID = 1, Name = "リンゴ", Price = 150 });
            _products.Add(new Product { ID = 2, Name = "バナナ", Price = 100 });
            _products.Add(new Product { ID = 3, Name = "メロン", Price = 800 });

            // DataGridView にバインド
            dataGridViewBL.DataSource        = _products;
            dataGridViewBL.AllowUserToAddRows = false;

            // ボタンクリックで BindingList にオブジェクト追加 → 自動反映
            btnAddBL.Click += (s, e) =>
            {
                int nextId = _products.Count + 1;
                _products.Add(new Product
                {
                    ID    = nextId,
                    Name  = $"商品{nextId}",
                    Price = nextId * 100
                });
            };
        }
    }

    // ── BindingList 用データクラス ──────────────────────
    public class Product
    {
        public int    ID    { get; set; }
        public string Name  { get; set; } = string.Empty;
        public int    Price { get; set; }

        // 【ポイント】引数付きコンストラクタを定義する場合は
        // 引数なしコンストラクタも明示的に書く必要があります。
        public Product() { }
    }
}

サンプルアプリケーション

※ サンプルアプリケーションは .NET 10 をターゲットとしています。

6. まとめ

DataGridView への行追加方法を状況別に整理します。

状況行追加の方法
DataSource なし(バインドなし)dataGridView1.Rows.Add(値1, 値2, ...)
DataTable をバインド中dataTable.Rows.Add(newRow)
BindingList をバインド中bindingList.Add(new オブジェクト)

バインドしている場合に dataGridView1.Rows.Add() を呼ぶと InvalidOperationException が発生します。「DataSource を設定しているかどうか」を最初に確認するのが、実装ミスを防ぐ最短ルートです。

DataGridView 関連記事

-Windows Forms