WPF 標準コントロールデモアプリ › DataGrid
DataGrid List
DataGrid はコレクションを行と列の表として表示するコントロールです。列の並べ替え、その場での編集、行の追加と削除を標準で備えています。
自動で作られる列
DataGrid は MultiSelector・Selector・ItemsControl を継承しています。既定の AutoGenerateColumns="True" では、バインドできる公開プロパティごとに 1 列を作ります。Zeta・Alpha・Mid の順に宣言した計測のクラスでは、アルファベット順ではなく宣言した順に列ができました。この順序は観測した結果で、ドキュメントが保証するものではありません。セッターのないプロパティは読み取り専用の列になりました。
計測した項目の型では、公開プロパティはすべて列になり、インデクサー this[string columnName] は列になりませんでした。デモアプリの項目は IDataErrorInfo を実装しているため、自動で作られた列は Name・Value と、インターフェイスから来た読み取り専用の Error 列でした。見せたくないメンバーがある型では、AutoGenerateColumns を False にし、DataGridTextColumn・DataGridCheckBoxColumn・DataGridComboBoxColumn などで列を宣言します。編集中のセルには、それぞれ TextBox・CheckBox・ComboBox が入りました。
行の追加・削除と、読み取り専用の表
CanUserAddRows と CanUserDeleteRows は、最下部の空の行から行を追加できるか、選んだ行を Delete キーで削除できるかです。どちらも既定値は True です。新規行はソースによって変わりました。List<T> と ObservableCollection<T> では表示され、配列と引数なしのコンストラクターを持たない型では表示されませんでした。その場合、CanUserAddRows は例外を出さずに False になったので、ユーザーが行を追加できない場合はソースを確認します。3 行のうち 2 行目を選んで Delete キーを押すと、その行がソースのコレクションから削除されました。
IsReadOnly は表全体の編集を止めます。IsReadOnly="True" にすると、CanUserAddRows は False になりました。列の側から編集を許すことはできません。列に IsReadOnly="False" を明示すると、列の値は False のままでしたが、そのセルで BeginEdit() を呼ぶと False が返り、編集は始まりませんでした。
| 条件 | 計測値 |
|---|---|
| 自動生成の列、宣言は Zeta、Alpha(get のみ)、Mid | Zeta(編集できる)、Alpha(読み取り専用)、Mid(編集できる) |
| 自動生成の列、デモの SampleItem(IDataErrorInfo) | Name(編集できる)、Value(編集できる)、Error(読み取り専用) |
| 2 列、FrozenColumnCount = 3(デモのスライダーの最大値) | 例外なし、表示できる、値 2 |
| デモのデータ、3 行目に Error、RowValidationRules 空: HasError の最初 / 編集後 | False / False |
| デモのデータ、3 行目に Error、RowValidationRules + DataErrorValidationRule: HasError の最初 / 編集後 | True / True |
| DataGrid が IsReadOnly=True: CanUserAddRows | False (Default) |
| 列に IsReadOnly=False を指定: IsReadOnly / BeginEdit() | False / False |
| 新規行 / CanUserAddRows、ItemsSource List<Person> | 表示される / True |
| 新規行 / CanUserAddRows、ItemsSource ObservableCollection<Person> | 表示される / True |
| 新規行 / CanUserAddRows、ItemsSource Person[](配列) | 表示されない / False |
| 新規行 / CanUserAddRows、ItemsSource 引数なしのコンストラクターが無い型の List<T> | 表示されない / False |
| 2 行目を選んで Delete キー: 残った項目 | 2 (Name 1, Name 3) |
列、読み取り専用の設定、検証、行の追加と削除。.NET 10 / Windows 11 で計測。
行の検証には規則が要る
RowValidationErrorTemplate は、行の検証に失敗したときの表示です。行が検証に失敗するのは規則が行を調べたときだけで、RowValidationRules は既定では空です。デモアプリのデータでは 3 行目が IDataErrorInfo.Error を返しますが、この行は編集した後も Validation.HasError になりませんでした。そのため、このデータで規則が無いままでは、テンプレートは表示されませんでした。RowValidationRules に DataErrorValidationRule を加えると、3 行目は検証エラーになりました。行にエラーを表示するなら、検証の規則を加えます。
編集と、編集中の並べ替え
フォーカスのある Name のセルで、キーボードでの編集を測りました。F2 キーで編集が始まり、セルに TextBox が入りました。”Changed” と入力して Esc キーを押すと、編集が終わり、ソースは変わりませんでした。もう一度 F2 キーを押して “Committed” と入力し、Enter キーを押すと、ソースに “Committed” が書き込まれました。
並べ替えは標準の機能です。列見出しをクリックすると昇順、もう一度で降順、3 回目で再び昇順になりました。3 回目で並べ替えが解除されるわけではありません。コードから解除する方法はWPFのDataGridのソートを初期化する方法で扱っています。
セルの編集中に項目へ SortDescription を加えると、InvalidOperationException が発生しました。引数なしの CommitEdit() や CancelEdit() を呼んでも防げず、どちらの後でも並べ替えで例外が発生しました。CommitEdit(DataGridEditingUnit.Row, true) か CancelEdit(DataGridEditingUnit.Row) の後は並べ替えられました。コードから並べ替え・絞り込み・グループ化をする前に、このように行の編集を終えます。
グループ化はコレクションビューの機能で、DataGrid がグループを表示するのは GroupStyle があるときだけです。GroupStyle がないと、グループ化したビューでもグループの見出しは現れませんでした。
画面上の行:仮想化、列の固定、1 行おきの背景
EnableRowVirtualization は、表示範囲外の DataGridRow のコンテナーを作らないかどうかです。EnableColumnVirtualization は DataGridColumn の定義には関わらず(定義は常に保たれる)、表示範囲外の列のセルと列見出しを作らないかどうかを決めます(列の仮想化はここでは測っていません)。既定値は行が True、列が False です。幅 360、高さ 200 の DataGrid に 1,000 行を入れると、DataGridRow は 11 個でした。既定では VirtualizingPanel.IsVirtualizingWhenGrouping が False なので、グループ化すると行の仮想化は止まり、GroupStyle を付けてグループ化すると 1,000 行すべてが作られました。同じ DataGrid でこれを True にすると、作られた行は 18 個でした。グループ化する表には設定します。
FrozenColumnCount は、横スクロールのときに動かさない、左端からの列の数です。既定値は 0 です。幅 200 の DataGrid に幅 100 の列を 4 つ並べて右へ 60 スクロールすると、1 列目は x = 7 から -53 へ動きました。FrozenColumnCount="1" では 1 列目は 7 のままで、2 列目だけが動きました。2 列に 3 を設定しても例外は出ず、2 に補正されました。
AlternatingRowBackground は 1 行おきの背景です。このプロパティだけを設定すれば足ります。AlternationCount は 2 になり、4 行が白と指定したブラシで交互になりました。
| 条件 | 計測値 |
|---|---|
| Name のセルで F2: IsEditing / 編集用の要素 | True / TextBox |
| "Changed" を入力して Esc: IsEditing / ソース | False / "Name 1" |
| F2、"Committed" を入力して Enter: ソース | "Committed" |
| 列の種類ごとの編集用の要素 | Text: TextBox, CheckBox: CheckBox, ComboBox: ComboBox |
| Name の見出しを 3 回クリック: SortDirection | Ascending -> Descending -> Ascending |
| セルの編集中に Items.SortDescriptions.Add(...) | InvalidOperationException |
| CommitEdit() の後 | InvalidOperationException |
| CancelEdit() の後 | InvalidOperationException |
| CommitEdit(DataGridEditingUnit.Row, true) の後 | 例外なし |
| CancelEdit(DataGridEditingUnit.Row) の後 | 例外なし |
| AlternatingRowBackground だけを指定: AlternationCount / 各行 | 2 / #FFFFFFFF, #FFD3D3D3, #FFFFFFFF, #FFD3D3D3 |
| 1,000 行: DataGridRow の数 / GroupItem の数 | 11 / 0 |
| 1,000 行をグループ化、GroupStyle あり: DataGridRow の数 / GroupItem の数 | 1000 / 10 |
| 1,000 行をグループ化、GroupStyle なし: DataGridRow の数 / GroupItem の数 | 11 / 0 |
| 1,000 行をグループ化、GroupStyle、IsVirtualizingWhenGrouping=True: DataGridRow の数 / GroupItem の数 | 18 / 1 |
| FrozenColumnCount=0、60 スクロール: 1 列目と 2 列目の x 座標 前 / 後 | 7, 107 / -53, 47 |
| FrozenColumnCount=1、60 スクロール: 1 列目と 2 列目の x 座標 前 / 後 | 7, 107 / 7, 47 |
編集、並べ替え、1 行おきの背景、仮想化、列の固定。.NET 10 / Windows 11 で計測。
そのほかの切り替えの既定値
SelectionModeとSelectionUnitの既定値はExtendedとFullRowです。- 幅を指定していない列の既定の幅と、その上限・下限である
ColumnWidth・MaxColumnWidth・MinColumnWidthは、SizeToHeader・Infinity・20 でした。 CanUserReorderColumns・CanUserResizeColumns・CanUserResizeRows・CanUserSortColumnsの既定値は 4 つともTrueです。RowDetailsTemplateを行の下にいつ表示するかのRowDetailsVisibilityModeはVisibleWhenSelected、横スクロールのときに詳細を動かさないかどうかのAreRowDetailsFrozenはFalseが既定値です。GridLinesVisibilityとHeadersVisibilityの既定値は、どちらもAllです。
デモアプリで試す

デモアプリの DataGrid のページには、ここまでのプロパティをすべて含む 20 のプロパティのまとまりごとに欄があります。データは Name と Value を持ち、IDataErrorInfo を実装した項目です。FrozenColumnCount のスライダーは、列が 2 つなのに 3 まで選べます。各欄の下の「Show Code」リンクで、その欄の XAML を表示できます。次の XAML は、FrozenColumnCount の欄(DataGridUsageControl.xaml)から、スタイルと周囲の GroupBox を省き、名前空間の宣言を加えたものです。Items は Name と Value を持つ項目のコレクションです。この断片は継承した DataContext を前提にしています。デモアプリでは DataGridUsageControl が Items を持つビューモデルを DataContext に設定しているので、断片だけで使う場合は、対応する DataContext を設定します。
<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Slider x:Name="PropertyFrozenColumnCount"
IsSnapToTickEnabled="True" Maximum="3" Minimum="0" />
<DataGrid x:Name="ResultFrozen" Height="150"
AutoGenerateColumns="False"
FrozenColumnCount="{Binding Value, ElementName=PropertyFrozenColumnCount}"
ItemsSource="{Binding Items}">
<DataGrid.Columns>
<DataGridTextColumn Width="150" Binding="{Binding Name}" Header="Frozen" />
<DataGridTextColumn Width="600" Binding="{Binding Value}" Header="Scrollable" />
</DataGrid.Columns>
</DataGrid>
</StackPanel>
関連するコントロールと記事
- WPF DataGrid の並び替えを実装する方法 — 並べ替えられる列と、その仕組みを扱います。
- WPFのDataGridのソートを初期化する方法 — コードから並べ替えを解除する方法を扱います。
- WPF DataGrid でセル編集中と表示時でコントロールを切り替える方法 — 表示用と編集用のセルのテンプレートを扱います。
- ListView —
GridViewで列を並べる、編集のない一覧です。
ソースコードと計測の方法
このページの挙動の記述は、すべて .NET 10 / Windows 11 で実際に動かして確かめたものです。計測には、このサイトのスクリーンショット生成ツールの DataGridDemoScene を使いました。列見出しのクリックは見出しのクリック処理(OnClick)を呼び、キー操作は表示したウィンドウへキーのイベントを送って再現しました。位置は計測した環境での値です。