業務系のデスクトップアプリには、必ずどこかでグリッドが必要になります。そして多くのチームは、いずれ「標準のグリッドではもう足りない」という壁にぶつかります。きっかけはたいてい、お客様からの「これ、Excel みたいに使えませんか?」という一言です。
本記事は、まさにその一歩手前のための内容です。.NET デスクトップにおける編集可能グリッドの主要な 4 つのファミリーを取り上げ、それぞれが本来何に向いているのか、そして「次のステージに移るべきサイン」とは何かを整理します。
4 つのファミリー
| ファミリー | 例 | 強み | 限界 |
|---|---|---|---|
| 標準 DataGridView | System.Windows.Forms.DataGridView | 無料、.NET に同梱、ドキュメント豊富 | 単一シート、数式なし、1 万行を超えると重い、セルタイプが古典的 |
| 標準 WPF DataGrid | System.Windows.Controls.DataGrid | MVVM 親和性が高い、仮想化スクロール | DataGridView と概念的にほぼ同じスコープ |
| プレミアム サードパーティ製グリッド | Telerik、DevExpress、Syncfusion など | 洗練された外観、高度なフィルタ・グルーピング | 結局は「データグリッド」であってスプレッドシートではない |
| スプレッドシートコンポーネント | ReoGrid、Spread.NET、Aspose.Cells | 複数シート、数式、結合セル、Excel 入出力 | 学習する API 表面が広い |
多くのチームがやってしまう失敗は、最初のファミリーに長く居続けたあと、いきなりプレミアム製のデータグリッドへ飛び移り、「結局それでも数式・結合セル・.xlsx ラウンドトリップは扱えない」と気付く、というパターンです。
「編集可能グリッド」が指すもの
コントロールを選ぶ前に、自分たちが本当に必要としているのは何かを正直に整理しておくと判断しやすくなります。デスクトップのグリッドはおおよそ次の 3 つに分けられます。
- レコードのリスト — 1 行 = 1 つの業務オブジェクト、列はそのプロパティ。編集すると 1 件のレコードが更新される。電話帳、在庫一覧、ユーザー管理。
- 表形式エディタ — (1) と似ているが、ワークフローは「この表に入力していく」ことに近い。一括価格更新、手入力データ、パラメータシート。
- ワークシート — 複数シート、他セルを参照する数式、シート間の集計、結合ヘッダー、条件付き書式。見積書、財務モデル、検査レポート。
DataGridView と WPF DataGrid は (1) に最適です。(2) もそれなりに扱えます。(3) には抽象が合いません。
DataGridView では足りなくなったときのサイン
- ユーザーから「列に数式を入れたい」と言われた(
=B2*C2) - ヘッダー行で セルを結合 する必要がある
- データが 複数シート をまたいで参照し合う
.xlsxの取り込み・書き出し で書式を保ったままラウンドトリップしたい- 仮想化していても 1 万行を超えると体感が重い
- 半数以上の列で 独自描画のカスタムセル を書いている
3 つ以上当てはまるなら、「データグリッド」を卒業して「スプレッドシート」に進むタイミングです。
スプレッドシート コンポーネントに切り替えると変わるもの
メンタルモデルが変わります。DataGridView ではオブジェクトのリストをバインドすると、グリッドがそれを描画します。スプレッドシートでは、セルそのものが真実の源 です。sheet["B2"] = 12 と書けば、その時点でグリッドにはもう 12 が表示されています。
// DataGridView — モデルが先
var products = repository.GetProducts();
dataGridView1.DataSource = products;
// ReoGrid — セルが先
var sheet = reoGridControl1.CurrentWorksheet;
sheet["A1"] = "Product"; sheet["B1"] = "Units"; sheet["C1"] = "Price";
sheet["A2"] = "Widget"; sheet["B2"] = 12; sheet["C2"] = 9.99;
sheet["D2"] = "=B2*C2"; // B2 や C2 が変われば自動的に再計算される
このセル中心のモデルこそが、数式・セル単位の Undo/Redo・Excel との直接的なラウンドトリップを可能にします。DataTable にバインドしたい場合は Worksheet.DataSource も使えますが、裏側は常に本物のスプレッドシートであることに変わりはありません。
トレードオフ
公平を期して、犠牲になる部分も挙げておきます。
- API 表面が広い。行・列・範囲・シート・スタイル・数式・条件付き書式・グラフ。
DataSourceを渡して列のプロパティを設定するだけ、というスタイルに比べて学ぶことは多くなります。 - バインディングの考え方が異なる。
BindingList<T>への双方向バインドは可能ですが、DataGridViewのような自動性はありません。通常は変更イベントを明示的に配線します。 - ライセンス費用。商用のスプレッドシートコンポーネントには価格があります。とはいえ、数式評価や条件付き書式、
.xlsx入出力を自前で作る工数と比べて検討してみてください。
「顧客一覧、1 行ずつ編集」程度の画面にスプレッドシートはオーバースペックです。逆に「四半期の見積書ワークシート、数式と結合ヘッダーつき」のような画面では、1 日で元が取れます。
簡単な意思決定フロー
- シングルシート、ほぼ参照、5 千行未満? → 標準
DataGridView/ WPFDataGridで十分。 - フィルタ・グルーピング・列の固定が多いが、結局はリスト? → プレミアムなサードパーティ製データグリッド。
- 「Excel みたいに」と言われる、または
.xlsxの入出力が必須? → スプレッドシート コンポーネント。 - サーバー側でレポートを生成するだけ、UI なし? → そもそもグリッドの問題ではない。C# で Excel ファイルを読み書きするを参照。
最も安上がりな選択は、シンプルな答えから始めて、要件が本当に求めてきたタイミングで切り替えることです。最も高くつくのは、3 ヶ月かけて DataGridView に数式を貼り付けようとすることです。
