C#のグリッド表示を完全解説|DataGridView・WPF DataGridの使い方とデータ表示・編集の基本

はじめに

C#で業務アプリや管理画面を作るとき、表形式でデータを表示する「グリッド」は非常によく使われます。顧客一覧、商品一覧、売上一覧、在庫管理、検索結果、設定画面など、複数件のデータを見やすく並べたい場面ではグリッド表示が欠かせません。

C#でグリッド表示を実装する代表的な方法には、Windows FormsのDataGridViewと、WPFのDataGridがあります。どちらも表形式のデータ表示・編集に使えますが、使い方や設計思想、データバインディングの考え方が異なります。

この記事では、C#のグリッド表示について、DataGridViewとWPF DataGridの基本から、データ表示、編集、検索、データベース連携、見た目のカスタマイズ、よくあるエラーまで解説します。

1. C#のグリッド表示とは?できることと主な用途

C#におけるグリッド表示とは、データを行と列で構成された表形式の画面に表示することです。Excelのように一覧で情報を確認できるため、業務アプリケーションでは非常に多く使われます。

たとえば、以下のようなデータを表示する場面でグリッドが使われます。

  • 顧客一覧

  • 商品一覧

  • 注文履歴

  • 売上一覧

  • 社員一覧

  • 在庫一覧

  • 検索結果

  • マスタ管理画面

C#では、デスクトップアプリの種類によって使用するグリッドコントロールが変わります。Windows FormsではDataGridView、WPFではDataGridを使うのが一般的です。

1-1. グリッド表示で実現できるデータ一覧・編集・検索

グリッド表示では、単にデータを一覧表示するだけでなく、さまざまな操作を実現できます。

代表的な機能は以下のとおりです。

  • 複数件のデータを一覧表示する

  • セル単位で値を編集する

  • 行を追加する

  • 選択行を削除する

  • 列ごとに並び替える

  • 条件に応じて検索・絞り込みを行う

  • チェックボックスで選択状態を管理する

  • コンボボックスで候補から値を選ばせる

  • ボタン列で詳細表示や削除処理を実行する

  • データベースの内容を表示・更新する

特に業務システムでは「検索条件を入力して、結果をグリッドに表示し、必要に応じて編集・保存する」という画面構成がよく使われます。

1-2. C#で使われる代表的なグリッドコントロール

C#でよく使われるグリッドコントロールには、主に以下があります。

Windows FormsではDataGridViewが代表的です。フォームに簡単に配置でき、コードから列や行を追加しやすいため、初心者にも扱いやすいグリッドコントロールです。

WPFではDataGridが代表的です。XAMLとデータバインディングを使って画面を構築するため、MVVMパターンとの相性がよく、見た目のカスタマイズもしやすいのが特徴です。

また、業務用途ではサードパーティ製の高機能グリッドコントロールを使うこともあります。標準コントロールだけでは実現しにくい高度なフィルター、集計、固定列、印刷、Excel出力などが必要な場合に検討されます。

1-3. Windows FormsとWPFでグリッドの扱いが違う理由

Windows FormsとWPFでは、画面の作り方そのものが異なります。

Windows Formsは、フォーム上にコントロールを配置し、イベントハンドラーに処理を書く開発スタイルが基本です。DataGridViewも、ボタンクリックやセル編集イベントなどを使って処理を実装することが多くなります。

一方、WPFはXAMLで画面を定義し、データバインディングによって画面とデータを結びつける開発スタイルです。DataGridItemsSourceにコレクションを設定して表示し、必要に応じてObservableCollectionINotifyPropertyChangedを使って画面更新を反映します。

つまり、Windows Formsは「画面部品を直接操作する」考え方が中心で、WPFは「データと画面をバインディングで連携させる」考え方が中心です。

1-4. DataGridViewとWPF DataGridの選び方

これからC#でグリッド表示を作る場合、Windows Formsを使うならDataGridView、WPFを使うならDataGridを選びます。

簡単な社内ツールや小規模な業務アプリを素早く作りたい場合は、Windows FormsのDataGridViewが扱いやすいです。フォームに配置して、少ないコードで一覧表示や編集を実装できます。

一方、画面デザインを柔軟に変更したい場合や、MVVMで保守性の高いアプリを作りたい場合は、WPFのDataGridが向いています。バインディングやテンプレートを活用することで、複雑な画面にも対応しやすくなります。

初心者がまずグリッド表示を理解するならDataGridViewから始めると分かりやすく、WPFやMVVMを学びながら本格的なアプリを作るならDataGridを学ぶのがおすすめです。

2. DataGridViewとは?Windows Formsで使うグリッド表示の基本

DataGridViewは、Windows Formsアプリケーションで表形式のデータを表示・編集するための標準コントロールです。C#のデスクトップアプリ開発では非常によく使われます。

データベースの検索結果、CSVの内容、クラスのリスト、DataTableなど、さまざまなデータを一覧表示できます。

2-1. DataGridViewの特徴と利用シーン

DataGridViewの主な特徴は以下のとおりです。

  • Windows Formsで標準利用できる

  • デザイナーから簡単に配置できる

  • コードで列や行を追加できる

  • DataTableList<T>をバインドできる

  • セル編集、行追加、削除に対応している

  • チェックボックス列、コンボボックス列、ボタン列を使える

  • セル単位・行単位で見た目を変更できる

利用シーンとしては、顧客管理、商品管理、在庫一覧、ログ表示、検索結果表示などがあります。

特に、Windows Formsで業務アプリを作る場合、DataGridViewは最も基本的なグリッドコントロールといえます。

2-2. DataGridViewをフォームに配置する方法

Visual Studioを使う場合、フォームデザイナーからDataGridViewを配置できます。

手順は以下のとおりです。

  1. Windows Formsプロジェクトを作成する

  2. フォームデザイナーを開く

  3. ツールボックスからDataGridViewを選択する

  4. フォーム上にドラッグ&ドロップする

  5. NameプロパティをdataGridView1などに設定する

コードで配置する場合は、以下のように記述できます。

C#
DataGridView grid = new DataGridView();
grid.Dock = DockStyle.Fill;
this.Controls.Add(grid);

Dock = DockStyle.Fillを指定すると、フォーム全体にグリッドを広げて表示できます。

2-3. 列を手動で追加する方法

DataGridViewでは、列をコードで手動追加できます。

C#
dataGridView1.Columns.Add("Id", "ID");
dataGridView1.Columns.Add("Name", "名前");
dataGridView1.Columns.Add("Price", "価格");

第1引数は列の内部名、第2引数は画面に表示されるヘッダー名です。

チェックボックス列を追加したい場合は、DataGridViewCheckBoxColumnを使います。

C#
var checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "IsSelected";
checkColumn.HeaderText = "選択";
dataGridView1.Columns.Add(checkColumn);

手動で列を定義する方法は、列名や表示順、列幅を細かく制御したい場合に便利です。

2-4. 行データをコードで追加する方法

列を手動で追加した場合、Rows.Addで行データを追加できます。

C#
dataGridView1.Columns.Add("Id", "ID");
dataGridView1.Columns.Add("Name", "名前");
dataGridView1.Columns.Add("Price", "価格");

dataGridView1.Rows.Add(1, "キーボード", 3000);
dataGridView1.Rows.Add(2, "マウス", 1500);
dataGridView1.Rows.Add(3, "モニター", 25000);

この方法は、固定データや簡単なサンプル表示には分かりやすいです。

ただし、実務ではDataTableList<T>DataSourceに設定して表示するケースが多くなります。データ件数が多い場合や、データベースと連携する場合は、バインディングを使う方が管理しやすくなります。

2-5. DataTableやListをDataGridViewに表示する方法

DataGridViewでは、DataSourceプロパティにデータを設定することで一覧表示できます。

DataTableを表示する例です。

C#
DataTable table = new DataTable();
table.Columns.Add("Id", typeof(int));
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Price", typeof(int));

table.Rows.Add(1, "キーボード", 3000);
table.Rows.Add(2, "マウス", 1500);
table.Rows.Add(3, "モニター", 25000);

dataGridView1.DataSource = table;

クラスのリストを表示する例です。

C#
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public int Price { get; set; }
}
C#
var products = new List<Product>
{
new Product { Id = 1, Name = "キーボード", Price = 3000 },
new Product { Id = 2, Name = "マウス", Price = 1500 },
new Product { Id = 3, Name = "モニター", Price = 25000 }
};

dataGridView1.DataSource = products;

DataTableはデータベースの結果表示と相性がよく、List<T>はオブジェクト指向でデータを扱いたい場合に向いています。

3. DataGridViewでデータを表示する基本実装

DataGridViewでデータを表示する方法には、主に手動追加とデータバインディングがあります。実務では、DataTableList<T>をバインドして表示する方法がよく使われます。

3-1. DataTableをバインドして一覧表示する

DataTableは、表形式のデータをメモリ上で扱うためのクラスです。列と行を持つため、DataGridViewとの相性が非常に良いです。

C#
private void Form1_Load(object sender, EventArgs e)
{
DataTable table = new DataTable();
table.Columns.Add("CustomerId", typeof(int));
table.Columns.Add("CustomerName", typeof(string));
table.Columns.Add("Email", typeof(string));

table.Rows.Add(1, "山田太郎", "yamada@example.com");
table.Rows.Add(2, "佐藤花子", "sato@example.com");
table.Rows.Add(3, "田中一郎", "tanaka@example.com");

dataGridView1.DataSource = table;
}

DataSourceDataTableを設定すると、列が自動生成され、行データが一覧表示されます。

3-2. Listやクラスのコレクションをバインドする

クラスのプロパティを列として表示したい場合は、List<T>を使います。

C#
public class Customer
{
public int CustomerId { get; set; }
public string CustomerName { get; set; }
public string Email { get; set; }
}
C#
private void Form1_Load(object sender, EventArgs e)
{
var customers = new List<Customer>
{
new Customer { CustomerId = 1, CustomerName = "山田太郎", Email = "yamada@example.com" },
new Customer { CustomerId = 2, CustomerName = "佐藤花子", Email = "sato@example.com" },
new Customer { CustomerId = 3, CustomerName = "田中一郎", Email = "tanaka@example.com" }
};

dataGridView1.DataSource = customers;
}

DataGridViewは、クラスのpublicプロパティを列として認識します。フィールドではなくプロパティとして定義することがポイントです。

編集や追加を画面に反映しやすくしたい場合は、BindingList<T>を使うと便利です。

C#
BindingList<Customer> customers = new BindingList<Customer>
{
new Customer { CustomerId = 1, CustomerName = "山田太郎", Email = "yamada@example.com" },
new Customer { CustomerId = 2, CustomerName = "佐藤花子", Email = "sato@example.com" }
};

dataGridView1.DataSource = customers;

3-3. AutoGenerateColumnsの使い方

AutoGenerateColumnsは、バインドしたデータから列を自動生成するかどうかを指定するプロパティです。

C#
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = customers;

trueにすると、データソースの列やプロパティに応じて自動的に列が作成されます。

一方、列を自分で定義したい場合はfalseにします。

C#
dataGridView1.AutoGenerateColumns = false;

dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
DataPropertyName = "CustomerId",
HeaderText = "顧客ID",
Name = "CustomerId"
});

dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
DataPropertyName = "CustomerName",
HeaderText = "顧客名",
Name = "CustomerName"
});

dataGridView1.DataSource = customers;

手動で列を定義する場合は、DataPropertyNameにデータソース側のプロパティ名または列名を指定します。

3-4. 列名・幅・表示順を設定する

自動生成された列でも、後から列名や幅を変更できます。

C#
dataGridView1.Columns["CustomerId"].HeaderText = "顧客ID";
dataGridView1.Columns["CustomerName"].HeaderText = "顧客名";
dataGridView1.Columns["Email"].HeaderText = "メールアドレス";

dataGridView1.Columns["CustomerId"].Width = 80;
dataGridView1.Columns["CustomerName"].Width = 150;
dataGridView1.Columns["Email"].Width = 250;

表示順を変更する場合は、DisplayIndexを使います。

C#
dataGridView1.Columns["CustomerName"].DisplayIndex = 0;
dataGridView1.Columns["CustomerId"].DisplayIndex = 1;
dataGridView1.Columns["Email"].DisplayIndex = 2;

不要な列を非表示にする場合は、Visiblefalseにします。

C#
dataGridView1.Columns["CustomerId"].Visible = false;

内部的には必要だが画面には表示したくないID列などでよく使います。

3-5. セルの書式や日付・数値表示を整える

日付や数値を見やすく表示するには、DefaultCellStyle.Formatを使います。

C#
dataGridView1.Columns["Price"].DefaultCellStyle.Format = "N0";
dataGridView1.Columns["CreatedAt"].DefaultCellStyle.Format = "yyyy/MM/dd";

数値を右寄せにする場合は、以下のように設定します。

C#
dataGridView1.Columns["Price"].DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight;

通貨形式で表示したい場合は、次のように指定できます。

C#
dataGridView1.Columns["Price"].DefaultCellStyle.Format = "C";

業務アプリでは、数値・金額・日付を見やすく整えるだけで、画面の使いやすさが大きく向上します。

4. DataGridViewでデータを編集・追加・削除する方法

DataGridViewは、データの表示だけでなく編集にも対応しています。セル編集、行追加、行削除、入力チェックを組み合わせることで、簡単なマスタ管理画面を作成できます。

4-1. セル編集を有効・無効にする設定

セル編集を禁止するには、ReadOnlyを使います。

C#
dataGridView1.ReadOnly = true;

特定の列だけ編集禁止にすることもできます。

C#
dataGridView1.Columns["CustomerId"].ReadOnly = true;

逆に、編集可能にする場合は次のようにします。

C#
dataGridView1.ReadOnly = false;

また、行単位の編集やセル単位の編集を制御する場合は、EditModeを設定します。

C#
dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;

EditOnEnterを指定すると、セルに入った時点で編集モードになります。入力作業を重視する画面では便利です。

4-2. ユーザーによる行追加を許可する方法

ユーザーが最終行から新しい行を追加できるようにするには、AllowUserToAddRowstrueにします。

C#
dataGridView1.AllowUserToAddRows = true;

行追加を禁止する場合はfalseにします。

C#
dataGridView1.AllowUserToAddRows = false;

データソースがDataTableの場合は、追加行がDataTableにも反映されやすいです。

List<T>を使う場合、行追加を安定して扱うにはBindingList<T>を使うのがおすすめです。

C#
BindingList<Product> products = new BindingList<Product>();
dataGridView1.DataSource = products;
dataGridView1.AllowUserToAddRows = true;

4-3. 選択行を削除する方法

選択行を削除するには、SelectedRowsを使います。

C#
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
{
if (!row.IsNewRow)
{
dataGridView1.Rows.Remove(row);
}
}

複数行選択を許可している場合は、選択されたすべての行が削除されます。

単一行だけ削除したい場合は、CurrentRowを使う方法もあります。

C#
if (dataGridView1.CurrentRow != null && !dataGridView1.CurrentRow.IsNewRow)
{
dataGridView1.Rows.Remove(dataGridView1.CurrentRow);
}

データベースと連携している場合、画面上から削除しただけではデータベースから削除されないことがあります。実際にDBへ反映するには、削除対象のIDを使ってDELETE文を実行するなどの保存処理が必要です。

4-4. 編集後の値を取得する方法

セルの値を取得するには、RowsCellsを使います。

C#
var value = dataGridView1.Rows[0].Cells["CustomerName"].Value;

現在選択している行の値を取得する場合は、次のように書けます。

C#
if (dataGridView1.CurrentRow != null)
{
int id = Convert.ToInt32(dataGridView1.CurrentRow.Cells["CustomerId"].Value);
string name = Convert.ToString(dataGridView1.CurrentRow.Cells["CustomerName"].Value);
}

編集直後の値を確実に反映したい場合は、EndEditを呼び出します。

C#
dataGridView1.EndEdit();

保存ボタンを押したときに編集内容を取得する場合は、保存処理の前にEndEditを呼ぶと安全です。

4-5. 入力チェックとエラー表示の基本

入力値をチェックするには、CellValidatingイベントを使います。

C#
private void dataGridView1_CellValidating(
object sender,
DataGridViewCellValidatingEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].Name == "Price")
{
if (!int.TryParse(e.FormattedValue.ToString(), out int price))
{
dataGridView1.Rows[e.RowIndex].ErrorText = "価格は数値で入力してください。";
e.Cancel = true;
}
else
{
dataGridView1.Rows[e.RowIndex].ErrorText = "";
}
}
}

e.Cancel = trueにすると、不正な値のままセルから移動できなくなります。

入力チェックでは、以下のような項目を確認することが多いです。

  • 必須入力か

  • 数値として正しいか

  • 日付として正しいか

  • 文字数が上限以内か

  • 重複していないか

  • マスタに存在する値か

エラー内容を明確に表示すると、ユーザーが修正しやすくなります。

5. WPF DataGridとは?WPFで使うグリッド表示の基本

WPF DataGridは、WPFアプリケーションで表形式のデータを表示・編集するためのコントロールです。XAMLとデータバインディングを使って、柔軟な画面を作成できます。

Windows FormsのDataGridViewよりも、デザインのカスタマイズやMVVMとの連携に向いています。

5-1. WPF DataGridの特徴と利用シーン

WPF DataGridの主な特徴は以下のとおりです。

  • XAMLで画面を定義できる

  • ItemsSourceでコレクションをバインドできる

  • ObservableCollection<T>と相性がよい

  • MVVMパターンで実装しやすい

  • 列ごとに表示形式を細かく設定できる

  • スタイルやテンプレートで見た目を柔軟に変更できる

  • 編集結果をバインディング経由でモデルに反映できる

利用シーンとしては、業務アプリ、管理ツール、検索画面、設定画面、マスタメンテナンス画面などがあります。

WPFで本格的なデスクトップアプリを作るなら、DataGridのバインディングとMVVMの考え方を理解しておくことが重要です。

5-2. XAMLでDataGridを配置する方法

WPFでは、XAMLにDataGridを記述して配置します。

XML
<DataGrid x:Name="CustomerGrid"
AutoGenerateColumns="True"
Margin="10" />

画面全体に配置する場合は、Gridレイアウトの中に入れることが多いです。

XML
<Grid>
<DataGrid x:Name="CustomerGrid"
AutoGenerateColumns="True"
Margin="10" />
</Grid>

コードビハインドからデータを設定する場合は、ItemsSourceにコレクションを代入します。

C#
CustomerGrid.ItemsSource = customers;

5-3. ItemsSourceによるデータバインディング

WPF DataGridでは、ItemsSourceに表示したいコレクションを設定します。

C#
public class Customer
{
public int CustomerId { get; set; }
public string CustomerName { get; set; }
public string Email { get; set; }
}
C#
var customers = new List<Customer>
{
new Customer { CustomerId = 1, CustomerName = "山田太郎", Email = "yamada@example.com" },
new Customer { CustomerId = 2, CustomerName = "佐藤花子", Email = "sato@example.com" }
};

CustomerGrid.ItemsSource = customers;

AutoGenerateColumnsTrueの場合、クラスのpublicプロパティから列が自動生成されます。

WPFでは、画面とデータを直接操作するよりも、バインディングで連携させる設計が基本です。

5-4. AutoGenerateColumnsの使い方

WPF DataGridにもAutoGenerateColumnsがあります。

XML
<DataGrid ItemsSource="{Binding Customers}"
AutoGenerateColumns="True" />

Trueにすると、バインドしたオブジェクトのプロパティをもとに列が自動生成されます。

列を自分で定義したい場合は、Falseにします。

XML
<DataGrid ItemsSource="{Binding Customers}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="顧客ID"
Binding="{Binding CustomerId}" />
<DataGridTextColumn Header="顧客名"
Binding="{Binding CustomerName}" />
<DataGridTextColumn Header="メール"
Binding="{Binding Email}" />
</DataGrid.Columns>
</DataGrid>

実務では、列名、幅、表示形式、編集可否を細かく制御するため、AutoGenerateColumns="False"にして列を明示的に定義することが多いです。

5-5. DataGridTextColumn・CheckBoxColumn・ComboBoxColumnの使い分け

WPF DataGridでは、列の種類を使い分けることで、さまざまな入力形式に対応できます。

文字列や数値を表示・編集する場合はDataGridTextColumnを使います。

XML
<DataGridTextColumn Header="商品名"
Binding="{Binding ProductName}" />

真偽値をチェックボックスで表示する場合はDataGridCheckBoxColumnを使います。

XML
<DataGridCheckBoxColumn Header="有効"
Binding="{Binding IsActive}" />

複数の候補から選択させる場合はDataGridComboBoxColumnを使います。

XML
<DataGridComboBoxColumn Header="カテゴリ"
SelectedItemBinding="{Binding Category}"
ItemsSource="{Binding Source={StaticResource CategoryList}}" />

単純な文字入力ならTextColumn、オン・オフならCheckBoxColumn、選択式ならComboBoxColumnと考えると分かりやすいです。

6. WPF DataGridでデータを表示・編集する実装方法

WPF DataGridでは、List<T>ObservableCollection<T>ItemsSourceに設定してデータを表示します。編集結果を画面やデータに反映するには、バインディングの仕組みを正しく理解する必要があります。

6-1. ListやObservableCollectionを表示する

単純に表示するだけなら、List<T>でも問題ありません。

C#
CustomerGrid.ItemsSource = new List<Customer>
{
new Customer { CustomerId = 1, CustomerName = "山田太郎", Email = "yamada@example.com" },
new Customer { CustomerId = 2, CustomerName = "佐藤花子", Email = "sato@example.com" }
};

ただし、画面表示後にコレクションへ追加・削除した内容をグリッドに反映したい場合は、ObservableCollection<T>を使います。

C#
public ObservableCollection<Customer> Customers { get; set; }
C#
Customers = new ObservableCollection<Customer>
{
new Customer { CustomerId = 1, CustomerName = "山田太郎", Email = "yamada@example.com" },
new Customer { CustomerId = 2, CustomerName = "佐藤花子", Email = "sato@example.com" }
};

CustomerGrid.ItemsSource = Customers;

ObservableCollection<T>は、要素の追加や削除を画面に通知できるため、WPFのグリッド表示でよく使われます。

6-2. MVVMでDataGridにデータをバインドする

MVVMでは、画面であるView、データとロジックを持つViewModel、データ構造を表すModelを分けて実装します。

ViewModelの例です。

C#
public class CustomerViewModel
{
public ObservableCollection<Customer> Customers { get; set; }

public CustomerViewModel()
{
Customers = new ObservableCollection<Customer>
{
new Customer { CustomerId = 1, CustomerName = "山田太郎", Email = "yamada@example.com" },
new Customer { CustomerId = 2, CustomerName = "佐藤花子", Email = "sato@example.com" }
};
}
}

XAMLでは、ItemsSourceCustomersをバインドします。

XML
<DataGrid ItemsSource="{Binding Customers}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="顧客ID"
Binding="{Binding CustomerId}" />
<DataGridTextColumn Header="顧客名"
Binding="{Binding CustomerName}" />
<DataGridTextColumn Header="メール"
Binding="{Binding Email}" />
</DataGrid.Columns>
</DataGrid>

画面側でDataContextを設定します。

C#
public MainWindow()
{
InitializeComponent();
DataContext = new CustomerViewModel();
}

MVVMを使うと、画面の処理とデータ処理を分離しやすくなり、保守性が高くなります。

6-3. 列ヘッダー・幅・並び順を設定する

WPF DataGridでは、列のHeaderで表示名を設定します。

XML
<DataGridTextColumn Header="顧客名"
Binding="{Binding CustomerName}" />

列幅はWidthで指定できます。

XML
<DataGridTextColumn Header="顧客名"
Binding="{Binding CustomerName}"
Width="200" />

残りの幅を自動的に使いたい場合は、*を指定します。

XML
<DataGridTextColumn Header="メール"
Binding="{Binding Email}"
Width="*" />

列の並び順は、XAMLに書いた順番で決まります。

XML
<DataGrid.Columns>
<DataGridTextColumn Header="顧客ID" Binding="{Binding CustomerId}" Width="80" />
<DataGridTextColumn Header="顧客名" Binding="{Binding CustomerName}" Width="150" />
<DataGridTextColumn Header="メール" Binding="{Binding Email}" Width="*" />
</DataGrid.Columns>

実務では、ID列を非表示にし、名称やステータスなどユーザーが確認しやすい列を左側に配置することが多いです。

6-4. セル編集と編集結果の反映方法

WPF DataGridでセルを編集すると、通常はバインド先のプロパティに値が反映されます。

XML
<DataGridTextColumn Header="顧客名"
Binding="{Binding CustomerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

Mode=TwoWayは、画面からデータへ、データから画面へ双方向に反映する設定です。

UpdateSourceTrigger=PropertyChangedを指定すると、入力中の変更がプロパティへ反映されやすくなります。ただし、通常のグリッド編集ではセル編集終了時に反映される動作でも十分な場合があります。

編集を禁止したい場合は、IsReadOnlyを使います。

XML
<DataGrid ItemsSource="{Binding Customers}"
IsReadOnly="True" />

特定の列だけ編集禁止にする場合は、列にIsReadOnlyを指定します。

XML
<DataGridTextColumn Header="顧客ID"
Binding="{Binding CustomerId}"
IsReadOnly="True" />

6-5. INotifyPropertyChangedで画面更新を反映する

データの値をコード側で変更したときに画面へ反映するには、モデルやViewModelでINotifyPropertyChangedを実装します。

C#
public class Customer : INotifyPropertyChanged
{
private string _customerName;

public int CustomerId { get; set; }

public string CustomerName
{
get => _customerName;
set
{
if (_customerName != value)
{
_customerName = value;
OnPropertyChanged(nameof(CustomerName));
}
}
}

public string Email { get; set; }

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

ObservableCollection<T>はコレクションの追加・削除を通知しますが、各要素のプロパティ変更を通知するには、要素側でINotifyPropertyChangedを実装する必要があります。

WPFでグリッド表示が更新されない場合、この違いを理解していないことが原因になりやすいです。

7. DataGridViewとWPF DataGridの違いを比較

DataGridViewとWPF DataGridは、どちらもC#でグリッド表示を行うためのコントロールですが、開発スタイルや得意分野が異なります。

7-1. 開発方式の違い:Windows FormsとWPF

DataGridViewはWindows Forms用のコントロールです。フォームデザイナーで配置し、コードビハインドにイベント処理を書くスタイルが基本です。

WPF DataGridはWPF用のコントロールです。XAMLで画面を定義し、データバインディングでデータを表示します。

Windows Formsは直感的に操作しやすく、簡単なアプリを素早く作るのに向いています。WPFは設計に慣れが必要ですが、画面の柔軟性や保守性を高めやすいです。

7-2. データバインディングの違い

DataGridViewでもデータバインディングは使えますが、画面部品を直接操作するコードも多くなりがちです。

C#
dataGridView1.DataSource = customers;

WPF DataGridでは、ItemsSourceにViewModelのプロパティをバインドする方法が基本です。

XML
<DataGrid ItemsSource="{Binding Customers}" />

WPFでは、データを変更すれば画面に反映される設計を目指すため、ObservableCollection<T>INotifyPropertyChangedが重要になります。

7-3. 見た目のカスタマイズ性の違い

DataGridViewでも色、フォント、列幅、ヘッダーなどは変更できます。ただし、複雑な見た目を作る場合はコードが増えやすくなります。

WPF DataGridは、スタイル、テンプレート、バインディング、トリガーを使って見た目を柔軟に変更できます。たとえば、条件に応じてセルの背景色を変えたり、セル内にボタンやアイコンを配置したりしやすいです。

デザイン性を重視する画面では、WPFの方が有利です。

7-4. MVVM対応のしやすさの違い

MVVMに対応しやすいのはWPF DataGridです。WPFはもともとバインディングを前提に設計されているため、ViewModelと連携しやすくなっています。

Windows Formsでも設計を工夫すれば処理を分離できますが、MVVMのような構成はWPFほど自然ではありません。

保守性やテストしやすさを重視する場合は、WPFとMVVMの組み合わせが向いています。

7-5. 初心者におすすめなのはどちらか

C#初心者がグリッド表示を学ぶなら、まずはWindows FormsのDataGridViewがおすすめです。

理由は、フォームに配置してすぐに動作を確認でき、列追加や行追加のコードも分かりやすいからです。

ただし、将来的に本格的なデスクトップアプリを作りたい場合や、MVVMを学びたい場合は、WPF DataGridも理解しておくべきです。

学習順としては、以下がおすすめです。

  1. DataGridViewでグリッド表示の基本を理解する

  2. DataTableList<T>のバインドを学ぶ

  3. WPF DataGridItemsSourceを学ぶ

  4. ObservableCollection<T>INotifyPropertyChangedを理解する

  5. MVVMでグリッド表示を設計する

8. C#グリッド表示でよく使う機能

グリッド表示では、一覧表示だけでなく、並び替え、検索、チェックボックス、コンボボックス、ボタン列などがよく使われます。

8-1. 並び替えを実装する方法

DataGridViewでは、列ヘッダーをクリックして並び替えできる場合があります。DataTableを使っている場合は、DataViewSortを使う方法もあります。

C#
DataView view = table.DefaultView;
view.Sort = "Price DESC";
dataGridView1.DataSource = view;

List<T>を使う場合は、LINQで並び替えて再設定できます。

C#
var sorted = products.OrderBy(p => p.Price).ToList();
dataGridView1.DataSource = sorted;

WPF DataGridでは、列ヘッダーのクリックによる並び替えが標準で利用できます。より細かく制御したい場合は、CollectionViewSourceを使います。

C#
var view = CollectionViewSource.GetDefaultView(Customers);
view.SortDescriptions.Add(
new SortDescription("CustomerName", ListSortDirection.Ascending));

8-2. フィルター・検索機能を追加する方法

DataTableの場合、DataView.RowFilterを使って絞り込みできます。

C#
DataView view = table.DefaultView;
view.RowFilter = "CustomerName LIKE '%山田%'";
dataGridView1.DataSource = view;

検索ボタンを押したときにテキストボックスの値で絞り込む例です。

C#
string keyword = textBoxSearch.Text.Replace("'", "''");
table.DefaultView.RowFilter = $"CustomerName LIKE '%{keyword}%'";

List<T>の場合は、LINQで検索できます。

C#
var filtered = products
.Where(p => p.Name.Contains(textBoxSearch.Text))
.ToList();

dataGridView1.DataSource = filtered;

WPFでは、CollectionViewSourceFilterイベントを使って絞り込みできます。

C#
var view = CollectionViewSource.GetDefaultView(Customers);
view.Filter = item =>
{
var customer = item as Customer;
return customer != null &&
customer.CustomerName.Contains(SearchKeyword);
};
view.Refresh();

検索機能では、大文字小文字、全角半角、空白、SQLインジェクションなどにも注意が必要です。

8-3. チェックボックス列を追加する方法

DataGridViewでチェックボックス列を追加するには、DataGridViewCheckBoxColumnを使います。

C#
var checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "IsSelected";
checkColumn.HeaderText = "選択";
dataGridView1.Columns.Add(checkColumn);

クラスにbool型のプロパティがある場合、自動的にチェックボックス列として表示されることもあります。

C#
public class Product
{
public bool IsSelected { get; set; }
public string Name { get; set; }
}

WPFではDataGridCheckBoxColumnを使います。

XML
<DataGridCheckBoxColumn Header="選択"
Binding="{Binding IsSelected}" />

複数行を選択して一括処理したい場合、チェックボックス列は非常に便利です。

8-4. コンボボックス列を追加する方法

DataGridViewでコンボボックス列を使うには、DataGridViewComboBoxColumnを追加します。

C#
var comboColumn = new DataGridViewComboBoxColumn();
comboColumn.Name = "Category";
comboColumn.HeaderText = "カテゴリ";
comboColumn.Items.Add("PC");
comboColumn.Items.Add("周辺機器");
comboColumn.Items.Add("ソフトウェア");

dataGridView1.Columns.Add(comboColumn);

データソースを使って選択肢を設定することもできます。

C#
comboColumn.DataSource = categories;
comboColumn.DisplayMember = "Name";
comboColumn.ValueMember = "Id";

WPFではDataGridComboBoxColumnを使います。

XML
<DataGridComboBoxColumn Header="カテゴリ"
SelectedValueBinding="{Binding CategoryId}"
DisplayMemberPath="Name"
SelectedValuePath="Id"
ItemsSource="{Binding Categories}" />

コンボボックス列は、ステータス、カテゴリ、担当者、区分など、決まった候補から選ばせたい項目に向いています。

8-5. ボタン列を追加して処理を実行する方法

DataGridViewでボタン列を追加するには、DataGridViewButtonColumnを使います。

C#
var buttonColumn = new DataGridViewButtonColumn();
buttonColumn.Name = "Detail";
buttonColumn.HeaderText = "詳細";
buttonColumn.Text = "表示";
buttonColumn.UseColumnTextForButtonValue = true;

dataGridView1.Columns.Add(buttonColumn);

ボタンがクリックされたときの処理は、CellContentClickイベントで実装します。

C#
private void dataGridView1_CellContentClick(
object sender,
DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0 && dataGridView1.Columns[e.ColumnIndex].Name == "Detail")
{
var id = dataGridView1.Rows[e.RowIndex].Cells["CustomerId"].Value;
MessageBox.Show($"ID: {id} の詳細を表示します。");
}
}

WPFでは、DataGridTemplateColumnを使ってセル内にボタンを配置できます。

XML
<DataGridTemplateColumn Header="詳細">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="表示"
Command="{Binding DataContext.ShowDetailCommand,
RelativeSource={RelativeSource AncestorType=DataGrid}}"
CommandParameter="{Binding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

ボタン列は、詳細表示、削除、編集画面の起動、ファイル出力などに使われます。

9. データベースの内容をグリッドに表示する方法

C#のグリッド表示では、データベースの内容を取得してDataGridViewやWPF DataGridに表示するケースが多くあります。

基本的な流れは以下です。

  1. データベースに接続する

  2. SQLを実行する

  3. 結果をDataTableやコレクションに入れる

  4. グリッドにバインドする

  5. 必要に応じて編集内容を保存する

9-1. SQL ServerのデータをDataGridViewに表示する

SQL ServerのデータをDataGridViewに表示する基本例です。

C#
using System.Data;
using Microsoft.Data.SqlClient;

string connectionString =
"Server=localhost;Database=SampleDb;Trusted_Connection=True;TrustServerCertificate=True;";

using var connection = new SqlConnection(connectionString);
using var command = new SqlCommand("SELECT Id, Name, Price FROM Products", connection);
using var adapter = new SqlDataAdapter(command);

DataTable table = new DataTable();
adapter.Fill(table);

dataGridView1.DataSource = table;

SqlDataAdapterを使うと、SELECT結果を簡単にDataTableへ読み込めます。

業務アプリでは、検索条件に応じてWHERE句を追加することも多いです。その場合は、文字列連結ではなくパラメータを使うようにします。

C#
command.CommandText = "SELECT Id, Name, Price FROM Products WHERE Name LIKE @Name";
command.Parameters.AddWithValue("@Name", "%" + keyword + "%");

9-2. SQLiteやAccessのデータを表示する

SQLiteでも基本的な流れは同じです。接続してSELECTを実行し、結果をDataTableに入れてグリッドに表示します。

C#
using System.Data;
using Microsoft.Data.Sqlite;

string connectionString = "Data Source=sample.db";

using var connection = new SqliteConnection(connectionString);
connection.Open();

using var command = connection.CreateCommand();
command.CommandText = "SELECT Id, Name, Price FROM Products";

using var reader = command.ExecuteReader();

DataTable table = new DataTable();
table.Load(reader);

dataGridView1.DataSource = table;

Accessの場合は、OleDbConnectionを使います。

C#
using System.Data;
using System.Data.OleDb;

string connectionString =
@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Data\sample.accdb;";

using var connection = new OleDbConnection(connectionString);
using var command = new OleDbCommand("SELECT Id, Name, Price FROM Products", connection);
using var adapter = new OleDbDataAdapter(command);

DataTable table = new DataTable();
adapter.Fill(table);

dataGridView1.DataSource = table;

SQLite、Access、SQL Serverのどれを使う場合でも、「取得結果をグリッドにバインドする」という考え方は共通です。

9-3. SELECT結果をDataTableに入れて表示する

データベースのSELECT結果をグリッドに表示する場合、DataTableを使うと実装が簡単です。

C#
private DataTable GetProducts()
{
DataTable table = new DataTable();

using var connection = new SqlConnection(connectionString);
using var command = new SqlCommand("SELECT Id, Name, Price FROM Products", connection);
using var adapter = new SqlDataAdapter(command);

adapter.Fill(table);

return table;
}

画面側では、取得したDataTableDataSourceに設定します。

C#
dataGridView1.DataSource = GetProducts();

このように、データ取得処理をメソッドに分けておくと、検索ボタンや再読み込み処理から再利用しやすくなります。

9-4. 編集内容をデータベースへ保存する流れ

グリッドで編集した内容をデータベースへ保存する場合、主に以下の方法があります。

  • DataTableの変更内容をSqlDataAdapterで更新する

  • 選択行の値を取得してUPDATE文を実行する

  • Entity FrameworkなどのORMを使って保存する

単純な更新例です。

C#
string sql = "UPDATE Products SET Name = @Name, Price = @Price WHERE Id = @Id";

using var connection = new SqlConnection(connectionString);
using var command = new SqlCommand(sql, connection);

command.Parameters.AddWithValue("@Name", name);
command.Parameters.AddWithValue("@Price", price);
command.Parameters.AddWithValue("@Id", id);

connection.Open();
command.ExecuteNonQuery();

保存ボタンを用意し、グリッドの編集内容を確定してから保存する流れにすると分かりやすいです。

C#
dataGridView1.EndEdit();

編集内容をすぐにDBへ反映するのではなく、「画面で編集」→「入力チェック」→「保存ボタン」→「DB更新」という流れにすると、エラー処理や確認処理を入れやすくなります。

9-5. Entity Frameworkとグリッド表示の基本

Entity Frameworkを使う場合、データベースのテーブルをエンティティクラスとして扱えます。

たとえば、商品テーブルを表示する場合は、以下のようなイメージです。

C#
using var context = new AppDbContext();

var products = context.Products.ToList();

dataGridView1.DataSource = products;

WPFでは、ObservableCollection<T>に変換してItemsSourceへ設定することもあります。

C#
Products = new ObservableCollection<Product>(
context.Products.ToList()
);

保存する場合は、変更を反映してSaveChangesを呼び出します。

C#
context.SaveChanges();

Entity Frameworkを使うとSQLを直接書く量を減らせますが、画面表示用のモデルとDBエンティティをそのまま共有すると、保守が難しくなることがあります。実務では、表示用DTOやViewModelを用意する設計もよく使われます。

10. C#グリッド表示の見た目をカスタマイズする方法

グリッドはデータを見やすく表示するための画面部品です。そのため、列幅、文字色、背景色、フォント、選択方法などを適切に調整することが重要です。

10-1. ヘッダーの文字・背景・配置を変更する

DataGridViewでヘッダーの見た目を変更する例です。

C#
dataGridView1.EnableHeadersVisualStyles = false;

dataGridView1.ColumnHeadersDefaultCellStyle.BackColor = Color.Navy;
dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;
dataGridView1.ColumnHeadersDefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleCenter;

EnableHeadersVisualStylesfalseにしないと、環境によってヘッダーのスタイル変更が反映されないことがあります。

WPFでは、ColumnHeaderStyleを使ってヘッダーのスタイルを変更できます。

XML
<DataGrid>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>

10-2. セルの文字色・背景色を変更する

DataGridViewでセル全体の標準スタイルを変更する例です。

C#
dataGridView1.DefaultCellStyle.Font = new Font("Meiryo UI", 10);
dataGridView1.DefaultCellStyle.ForeColor = Color.Black;
dataGridView1.DefaultCellStyle.BackColor = Color.White;

交互に行の色を変えると、一覧が読みやすくなります。

C#
dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray;

WPFでは、RowStyleCellStyleを使います。

XML
<DataGrid>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Padding" Value="4" />
</Style>
</DataGrid.CellStyle>
</DataGrid>

10-3. 条件に応じて行やセルの色を変える

DataGridViewでは、CellFormattingイベントを使うと、値に応じてセルの色を変更できます。

C#
private void dataGridView1_CellFormatting(
object sender,
DataGridViewCellFormattingEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].Name == "Stock")
{
if (e.Value != null && int.TryParse(e.Value.ToString(), out int stock))
{
if (stock <= 0)
{
e.CellStyle.BackColor = Color.LightPink;
e.CellStyle.ForeColor = Color.Red;
}
}
}
}

在庫が0以下、期限切れ、エラー状態、未処理ステータスなどを色で強調すると、ユーザーが重要な情報に気づきやすくなります。

WPFでは、StyleDataTriggerを使って条件付きの見た目を設定できます。

XML
<DataGridTextColumn Header="在庫" Binding="{Binding Stock}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Stock}" Value="0">
<Setter Property="Background" Value="LightPink" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>

10-4. 行選択・セル選択の動作を変更する

DataGridViewで行全体を選択するには、SelectionModeを設定します。

C#
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView1.MultiSelect = false;

セル単位で選択したい場合は、次のようにします。

C#
dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;

WPF DataGridでは、SelectionModeSelectionUnitを使います。

XML
<DataGrid SelectionMode="Single"
SelectionUnit="FullRow" />

複数選択を許可する場合は、SelectionMode="Extended"を指定します。

XML
<DataGrid SelectionMode="Extended"
SelectionUnit="FullRow" />

業務画面では、詳細表示や削除処理の対象を明確にするため、行全体選択にすることが多いです。

10-5. グリッド線・余白・フォントを調整する

DataGridViewでグリッド線や余白を調整する例です。

C#
dataGridView1.GridColor = Color.LightGray;
dataGridView1.RowTemplate.Height = 28;
dataGridView1.DefaultCellStyle.Padding = new Padding(4);
dataGridView1.DefaultCellStyle.Font = new Font("Meiryo UI", 10);

列幅を自動調整するには、以下を使います。

C#
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;

WPFでは、GridLinesVisibilityRowHeightを設定できます。

XML
<DataGrid GridLinesVisibility="All"
RowHeight="28"
FontSize="14" />

見た目の調整では、単に装飾するだけでなく、データの読みやすさ、操作しやすさ、誤操作の防止を意識することが重要です。

11. C#グリッド表示でよくあるエラーと対処法

C#でグリッド表示を実装していると、「データが表示されない」「列が出ない」「編集が反映されない」「表示が重い」などの問題が起きることがあります。

11-1. データが表示されない原因

データが表示されない場合、まず確認すべきポイントは以下です。

  • DataSourceまたはItemsSourceが設定されているか

  • データ件数が0件ではないか

  • クラスのプロパティがpublicになっているか

  • AutoGenerateColumnsが適切に設定されているか

  • DataPropertyNameBindingの名前が間違っていないか

  • UIスレッド以外からグリッドを更新していないか

DataGridViewでよくあるのは、列を手動定義しているのにDataPropertyNameを設定していないケースです。

C#
new DataGridViewTextBoxColumn
{
HeaderText = "顧客名",
DataPropertyName = "CustomerName"
};

WPFでは、Bindingのプロパティ名が間違っていると表示されません。

XML
<DataGridTextColumn Header="顧客名"
Binding="{Binding CustomerName}" />

11-2. 列が自動生成されない原因

列が自動生成されない場合、AutoGenerateColumnsfalseになっていないか確認します。

DataGridViewでは以下です。

C#
dataGridView1.AutoGenerateColumns = true;

WPFでは以下です。

XML
<DataGrid AutoGenerateColumns="True" />

また、バインドしているクラスにpublicプロパティがない場合も列が生成されません。

C#
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}

フィールドだけを定義している場合、期待どおりに表示されないことがあります。

C#
public class Product
{
public int Id;
public string Name;
}

グリッドに表示するデータは、基本的にpublicプロパティとして定義しましょう。

11-3. 編集した値が反映されない原因

DataGridViewで編集値が取得できない場合は、編集が確定していない可能性があります。保存前にEndEditを呼び出します。

C#
dataGridView1.EndEdit();

バインディングを使っている場合は、BindingSource側も確定します。

C#
bindingSource1.EndEdit();

WPFで編集値が反映されない場合は、Bindingのモードや更新タイミングを確認します。

XML
<DataGridTextColumn Binding="{Binding CustomerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

また、コード側でプロパティを変更しても画面が更新されない場合は、INotifyPropertyChangedが実装されているか確認します。

11-4. バインド時に例外が出る原因

バインド時に例外が出る原因には、以下があります。

  • 列名やプロパティ名が間違っている

  • コンボボックス列の値が候補に存在しない

  • nullを許容していない型にnullが入っている

  • データ型が一致していない

  • DBから取得した列名と画面側の設定が一致していない

DataGridViewComboBoxColumnで特に多いのが、セルの値がItemsDataSourceに存在しないケースです。この場合、「DataGridViewComboBoxCell の値が有効ではありません」というエラーが出ることがあります。

対策として、候補データと実データの値を一致させることが重要です。

C#
comboColumn.ValueMember = "Id";
comboColumn.DisplayMember = "Name";
comboColumn.DataSource = categories;

実データ側のCategoryIdが、候補リストのIdに存在するか確認しましょう。

11-5. 表示が重い・遅いときの改善方法

グリッド表示が重い場合、以下を見直します。

  • 一度に表示する件数が多すぎないか

  • 不要な列まで表示していないか

  • セルごとの描画処理が重くないか

  • CellFormattingで重い処理をしていないか

  • データベースから必要以上の件数を取得していないか

  • ページングを導入できないか

  • 仮想モードや仮想化を使えるか

DataGridViewでは大量データ向けにVirtualModeを検討できます。

C#
dataGridView1.VirtualMode = true;

WPF DataGridでは、仮想化が有効か確認します。

XML
<DataGrid VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling" />

ただし、根本的には「必要なデータだけ取得して表示する」設計が重要です。数万件以上のデータを一度に表示するのではなく、検索条件やページングで絞り込む方が実用的です。

12. C#のグリッド表示を実装するときのベストプラクティス

C#でグリッド表示を作るときは、ただ表示できればよいわけではありません。保守性、パフォーマンス、入力チェック、データ保存の流れを考えて設計することが重要です。

12-1. 画面表示用モデルを用意する

データベースのエンティティをそのままグリッドに表示すると、不要な列まで表示されたり、画面都合の項目を追加しにくくなったりします。

そのため、画面表示用のモデルを用意すると管理しやすくなります。

C#
public class ProductGridRow
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string CategoryName { get; set; }
public int Price { get; set; }
public bool IsSelected { get; set; }
}

表示用モデルを使うと、チェックボックス列や表示用の名称、計算結果などを扱いやすくなります。

12-2. UI処理とデータ処理を分ける

グリッドのイベント内にSQLや業務ロジックを直接書きすぎると、コードが複雑になり、保守しにくくなります。

たとえば、以下のように役割を分けると整理しやすくなります。

  • 画面:ボタン操作、グリッド表示、入力値取得

  • サービス:検索、登録、更新、削除などの業務処理

  • リポジトリ:データベースアクセス

  • モデル:データ構造

Windows Formsでも、すべてをフォームクラスに書くのではなく、データ取得処理や保存処理を別クラスに分けると保守しやすくなります。

WPFでは、MVVMを使ってView、ViewModel、Modelを分離するのが基本です。

12-3. 大量データはページングや仮想化を検討する

大量データをグリッドに表示すると、画面の表示やスクロールが重くなります。

対策として、以下を検討します。

  • 検索条件を必須にする

  • 最大表示件数を制限する

  • ページングを導入する

  • 必要な列だけ取得する

  • DB側で並び替え・絞り込みを行う

  • 仮想化を利用する

SQLでページングする例です。

SQL
SELECT Id, Name, Price
FROM Products
ORDER BY Id
OFFSET @Offset ROWS
FETCH NEXT @PageSize ROWS ONLY;

画面側で全件取得してから絞り込むより、データベース側で必要な分だけ取得する方が効率的です。

12-4. 入力チェックと保存処理を明確に分ける

グリッド編集では、入力チェックと保存処理を分けて考えることが大切です。

おすすめの流れは以下です。

  1. ユーザーがグリッドを編集する

  2. 保存ボタンを押す

  3. 編集を確定する

  4. 入力チェックを行う

  5. 問題があればエラー表示する

  6. 問題がなければデータベースへ保存する

  7. 保存後に再読み込みする

保存処理の前には、編集内容を確定します。

C#
dataGridView1.EndEdit();

入力チェックとDB保存を同じ処理に詰め込みすぎると、エラー時の扱いが難しくなります。チェック処理を別メソッドに分けておくと、後から修正しやすくなります。

12-5. 保守しやすいグリッド設計のポイント

保守しやすいグリッドを作るには、以下の点を意識します。

  • 列名やバインド名を分かりやすくする

  • 表示列と内部ID列を分ける

  • 自動生成列に頼りすぎない

  • 入力チェックを明確にする

  • 保存処理のタイミングを統一する

  • 大量データを一度に表示しない

  • 見た目の設定を共通化する

  • DBエンティティをそのまま画面に出しすぎない

  • 画面操作とデータ処理を分離する

特に、列の自動生成はサンプルでは便利ですが、実務では列順や表示名が変わると困ることがあります。そのため、本番画面では列を明示的に定義する方が安定します。

13. C#グリッド表示に関するよくある質問

ここでは、C#のグリッド表示でよくある疑問について解説します。

13-1. C#で表形式データを表示するには何を使えばよい?

Windows FormsならDataGridView、WPFならDataGridを使うのが基本です。

簡単な一覧表示や小規模な業務ツールなら、DataGridViewが扱いやすいです。WPFでMVVMを使った本格的なアプリを作る場合は、WPF DataGridが向いています。

データソースには、DataTableList<T>BindingList<T>ObservableCollection<T>などを使います。

13-2. DataGridViewとDataGridの違いは?

DataGridViewはWindows Forms用、DataGridはWPF用のグリッドコントロールです。

DataGridViewはフォーム上に配置してイベントで処理するスタイルに向いています。シンプルで分かりやすく、初心者にも扱いやすいです。

WPF DataGridはXAMLとデータバインディングを使い、MVVMとの相性が良いです。見た目のカスタマイズ性も高く、本格的なWPFアプリに向いています。

13-3. DataGridViewでListを表示できる?

はい、DataGridViewList<T>を表示できます。

C#
var products = new List<Product>
{
new Product { Id = 1, Name = "キーボード", Price = 3000 },
new Product { Id = 2, Name = "マウス", Price = 1500 }
};

dataGridView1.DataSource = products;

ただし、表示されるのはpublicプロパティです。フィールドではなくプロパティを定義しましょう。

C#
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public int Price { get; set; }
}

行の追加や削除を画面に反映したい場合は、BindingList<T>を使うと便利です。

13-4. WPF DataGridで編集を禁止するには?

WPF DataGrid全体を編集禁止にするには、IsReadOnly="True"を指定します。

XML
<DataGrid ItemsSource="{Binding Customers}"
IsReadOnly="True" />

特定の列だけ編集禁止にすることもできます。

XML
<DataGridTextColumn Header="顧客ID"
Binding="{Binding CustomerId}"
IsReadOnly="True" />

表示専用の一覧画面では、グリッド全体を読み取り専用にしておくと誤操作を防げます。

13-5. グリッドにデータベースの内容を表示するには?

基本的な流れは、データベースからSELECTでデータを取得し、DataTableやコレクションに入れてグリッドへバインドします。

DataGridViewの場合は、以下のようにDataSourceへ設定します。

C#
dataGridView1.DataSource = table;

WPF DataGridの場合は、ItemsSourceへ設定します。

C#
CustomerGrid.ItemsSource = customers;

SQL Server、SQLite、Accessなど、データベースの種類が違っても、取得した結果を表形式データやオブジェクトのリストに変換してグリッドへ表示する考え方は同じです。

まとめ

C#でグリッド表示を実装する場合、Windows FormsではDataGridView、WPFではDataGridを使うのが基本です。

DataGridViewは、フォームに配置してすぐに使える分かりやすいグリッドコントロールです。DataTableList<T>DataSourceに設定するだけで、簡単に一覧表示できます。セル編集、行追加、削除、チェックボックス列、コンボボックス列、ボタン列などにも対応しており、業務アプリでよく使われます。

WPF DataGridは、XAMLとデータバインディングを活用して柔軟な画面を作れるグリッドコントロールです。ItemsSourceObservableCollection<T>INotifyPropertyChangedを理解すると、MVVMに沿った保守性の高いアプリを作りやすくなります。

グリッド表示を実装するときは、単にデータを表示するだけでなく、編集、入力チェック、検索、並び替え、データベース保存、パフォーマンス、見た目の調整まで考えることが重要です。

初心者はまずDataGridViewで基本を学び、その後WPF DataGridやMVVMに進むと、C#のグリッド表示を体系的に理解しやすくなります。