
DataGridViewは、DataGridを拡張したクラスです。Differences Between the Windows Forms DataGridView and DataGrid Controls | Microsoft Learn
DataGridView dataGridView = new DataGridView();
DataGridViewColumn column1 = new DataGridViewTextBoxColumn() { HeaderText = "A" };
DataGridViewColumn column2 = new DataGridViewTextBoxColumn() { HeaderText = "B" };
dataGridView.Columns.AddRange(column1, column2);
dataGridView.Rows.Add("A1", "B1");
dataGridView.Rows.Add("A2", "B2");
| 型 | プロパティ | 内容 |
|---|---|---|
| object | DataSource | データソース |
| string | DataMember | データソースに複数のテーブルまたはリストが含まれるときに、対象とするそれの名前。単一のテーブルまたはリストならば、指定する必要はない |
| DataGridViewColumnCollection | Columns | すべての列 (DataGridViewColumn) を含むコレクション。ただし行ヘッダーを含む列は除く |
| DataGridViewRowCollection | Rows | すべての行 (DataGridViewRow) を含むコレクション。ただし列ヘッダーを含む行は除く |
| DataGridViewCell | Item[Int32, Int32] | 指定の列の、指定の行にあるセル |
| DataGridViewHeaderCell | TopLeftHeaderCell | 左上隅にあるヘッダーセル。MultiSelectがtrueのとき、これをクリックするとSelectAll()が呼ばれる OnTopLeftHeaderMouseDown - DataGridViewMethods.cs |
| int | ColumnCount | 表示されている列の数。これに設定すると、その数になるように列が削除または追加される
これから取得するのは ユーザーに表示されている列の数は、DisplayedColumnCount()で得られる |
| int | RowCount | 表示されている行の数。これに設定すると、その数になるように行が削除または追加される
これから取得するのは ユーザーに表示されている行の数は、DisplayedRowCount()で得られる。AllowUserToAddRowsがtrueならば、追加するための行もこの数に含まれる |
| bool | IsCurrentCellDirty | trueならば、現在のセルがコミット (確定) されていないデータを含む |
| bool | IsCurrentRowDirty | trueならば、現在の行がコミット (確定) されていないデータを含む |
| bool | IsCurrentCellInEditMode | trueならば、現在のセルが編集中 |
| Control | EditingControl | セルが編集モードのとき、そのセルでホストされているコントロール。編集モードでなければnull |
| Panel | EditingPanel | EditingControlを格納しているパネル。EditingControlとは異なり、編集モードとは無関係につねに利用できる |
| int | HorizontalScrollingOffset | 水平にスクロールされているピクセル数 |
| int | VerticalScrollingOffset | 垂直にスクロールされているピクセル数 |
| Rectangle | DisplayRectangle | コントロールの表示領域を表す四角形 |
| 型 | プロパティ | 内容 |
|---|---|---|
| DataGridViewCell | FirstDisplayedCell | 表示されている最初のセル。通常は左上隅のセルだが、RTL言語では右上となる。またこれに設定すると、このセルが表示されるようにスクロールする |
| int | FirstDisplayedScrollingColumnIndex | 表示されている最初の列のインデックス |
| int | FirstDisplayedScrollingRowIndex | 表示されている最初の行のインデックス。表示される前か表示する行がなければ-1が返されるが、-1を設定するとArgumentOutOfRangeExceptionとなる |
| DataGridViewCell | CurrentCell | 現在アクティブなセル。アクティブなセルがなければnull |
| Point | CurrentCellAddress | 現在アクティブなセルの行と列のインデックス。アクティブなセルがないならば、そのインデックスは(-1,-1)となる CurrentCellAddress - DataGridView.cs |
| DataGridViewRow | CurrentRow | 現在アクティブなセルを格納している行。アクティブなセルがなければnull。これを変更するには、アクティブにしたい行にあるセルにCurrentCellを設定する |
| DataGridViewSelectedCellCollection | SelectedCells | ユーザーによって選択されているセルのコレクション |
| DataGridViewSelectedColumnCollection | SelectedColumns | ユーザーによって選択されている列のコレクション (これが機能するのは、SelectionModeがFullColumnSelectまたはColumnHeaderSelectのときだけ) |
| DataGridViewSelectedRowCollection | SelectedRows | ユーザーによって選択されている行のコレクション
(これが機能するのは、SelectionModeがFullRowSelectまたはRowHeaderSelectのときだけ)
(コレクション内の項目の順は、選択された順と一致する保証はない Remarks - DataGridViewSelectedRowCollection Class (System.Windows.Forms) | Microsoft Learn)
逆にプログラムで行を選択するには、DataGridViewRow.Selectedをtrueに設定する |
| DataGridViewColumn | SortedColumn | 並べ替えの列。読取専用。並べ替えられていないならnull。設定するにはSort()を呼ぶ。並べ替えを独自に実装しているならば、この値は意味をなさない |
| SortOrder | SortOrder | 並べ替えの順。読取専用。設定するにはSort()を呼ぶ。並べ替えを独自に実装しているならば、この値は意味をなさない |
| 型 | プロパティ | 内容 | 既定値 |
|---|---|---|---|
| bool | AutoGenerateColumns | trueならば、DataSourceまたはDataMemberが設定されているときに、列が自動的に作成される。ただしColumnMappingがMappingType.Hiddenのように、非表示にされている列は作成されない | true |
| DataGridViewAutoSizeColumnsMode | AutoSizeColumnsMode | 列の幅を決定する方法 ※1
行ヘッダーの幅はRowHeadersWidthSizeModeで指定する。Fillとしたとき、表示領域が小さいことによりMinimumWidthの幅を下回るときには、水平スクロールが表示される |
None |
| DataGridViewAutoSizeRowsMode | AutoSizeRowsMode | 行の高さを幅を決定する方法 ※1 | None |
※1 パフォーマンスを考慮するならば自動サイズを用いない、または表示されているヘッダーやセルに基づいてサイズ調整させます。自動サイズ変更の効率的な使用 - DataGridView コントロールの拡大縮小に関するベスト プラクティス - Windows Forms .NET Framework | Microsoft Learn
| 型 | プロパティ | 内容 | 既定値 |
|---|---|---|---|
| bool | AllowUserToAddRows | trueならば、ユーザーに新しい行の追加オプションが表示される | true |
| bool | AllowUserToDeleteRows | trueならば、ユーザーは行を削除できる | true |
| bool | AllowUserToOrderColumns | trueならば、ユーザーは列の順を変更できる | false |
| bool | AllowUserToResizeColumns | trueならば、ユーザーは列のサイズを変更できる。行ヘッダーは、RowHeadersWidthSizeModeで指定する | true |
| bool | AllowUserToResizeRows | trueならば、ユーザーは行のサイズを変更できる。列ヘッダーは、ColumnHeadersHeightSizeModeで指定する | true |
| int | RowHeadersWidth | 行ヘッダーの幅。4以上、32768以下 RowHeadersWidth - DataGridView.cs | 43 |
| int | ColumnHeadersHeight | 列ヘッダーの高さ。4以上、32768以下 | 23 |
| DataGridViewRowHeadersWidthSizeMode | RowHeadersWidthSizeMode | 行ヘッダーの幅の調整方法 | EnableResizing |
| DataGridViewColumnHeadersHeightSizeMode | ColumnHeadersHeightSizeMode | 列ヘッダーの高さの調整方法 | EnableResizing |
| bool | ReadOnly | trueならば、ユーザーはセルを編集できない | false |
| bool | MultiSelect | trueならば、ユーザーはセル、行や列を同時に複数選択できる | true |
| DataGridViewSelectionMode | SelectionMode | セルの選択方法 | |
| DataGridViewEditMode | EditMode | セルの編集を開始する方法 | EditOnKeystrokeOrF2 |
| DataGridViewRow | RowTemplate | コントロール内のすべての行のテンプレートを表す行。これは新規に作成される行に適用されるため、行を追加する前に設定しておく。またこれを変更しても、既存の行には影響しない (列のテンプレートはDataGridViewColumn.CellTemplateで指定する) | |
| DataGridViewClipboardCopyMode | ClipboardCopyMode | ユーザーがセルのテキストの値をクリップボードへコピー可能か、そして行や列ヘッダーのテキストをそれに含めるかどうか | |
| bool | ShowCellToolTips | trueならば、セルの上でマウス ポインターが停止したときにツールチップを表示する | true |
| bool | ShowCellErrors | trueならば、セルエラーを表示する | true |
| bool | ShowEditingIcon | trueならば、セルの編集中に行ヘッダーに編集グリフ (editing glyph) を表示する (グリフを表示する領域が不足するならば、グリフは表示されない) | true |
| bool | ShowRowErrors | trueならば、DataGridViewRow.ErrorTextが空文字列ではないときに行ヘッダーにエラーグリフ (error glyphs) を表示する (グリフを表示する領域が不足するならば、グリフは表示されない) | true |
| bool | ColumnHeadersVisible | trueならば、列ヘッダーを表示する | true |
| bool | RowHeadersVisible | trueならば、行ヘッダーを格納している列を表示する | true |
| bool | StandardTab | trueならば、Tabキーでタブ オーダーの次のコントロールにフォーカスが移動する。さもなくば次のセルのフォーカスが移動する | false |
| bool | VirtualMode | trueならば、独自のデータ管理操作を提供している。仮想モード | false |
| 区分 | 型 | プロパティ | 内容 |
|---|---|---|---|
| 既定値 | DataGridViewCellStyle | DefaultCellStyle | 他のスタイルが設定されていないときに適用される、既定のセル スタイル |
| DataGridViewCellStyle | RowsDefaultCellStyle | 行のセル | |
| DataGridViewCellStyle | AlternatingRowsDefaultCellStyle | 奇数行に適用 | |
| DataGridViewCellStyle | RowHeadersDefaultCellStyle | 行ヘッダーのセルに適用 ※1 | |
| DataGridViewCellStyle | ColumnHeadersDefaultCellStyle | 列ヘッダーに適用。左上隅のヘッダーセル (TopLeftHeaderCell) も含む ※1 | |
| 境界線 (組み込みのスタイル) | Color | GridColor | セルのグリッド線 (grid lines) の色 |
| BorderStyle | BorderStyle | 境界線のスタイル (border style)。FixedSingle、Fixed3Dなど | |
| DataGridViewCellBorderStyle | CellBorderStyle | Single、SingleVertical、SingleHorizontal、Raised、Sunkenなど | |
| DataGridViewHeaderBorderStyle | ColumnHeadersBorderStyle | Single、Raised、Sunkenなど | |
| DataGridViewHeaderBorderStyle | RowHeadersBorderStyle | ||
| 境界線 | DataGridViewAdvancedBorderStyle | AdvancedCellBorderStyle | |
| DataGridViewAdvancedBorderStyle | AdvancedColumnHeadersBorderStyle | ||
| DataGridViewAdvancedBorderStyle | AdvancedRowHeadersBorderStyle | ||
| DataGridViewAdvancedBorderStyle | AdjustedTopLeftHeaderBorderStyle | ||
| bool | EnableHeadersVisualStyles | trueならば、視覚スタイルが有効なときに、ヘッダーにそれを適用する。既定はtrue |
列ごとの既定のスタイルは、DataGridViewColumn.DefaultCellStyleで指定します。
以下のインターフェイスを実装するオブジェクトを、データソースに指定できます。Remarks - DataGridView.DataSource Property (System.Windows.Forms) | Microsoft Learn
DataSourceを変更すると、CurrentCellはnullになります。DataSource - DataGridView.cs
DataSourceにしているオブジェクトを更新してもそれがDataGridViewに反映されないならば、BindingList<T>やBindingSourceを介して設定します。c# - Refresh DataGridView when updating data source - Stack Overflow
DataGridViewが親コントロールに含まれていなかったり、データソースとバインドする (結びつける) 列が存在しないときは何も表示されず、RowCountは0となります。
DataSourceへ設定後にそれへアクセスしたときに、CurrencyManager.get_Item(Int32 index)から「インデックス n に値がありません。(Index n does not have a value)」としてIndexOutOfRangeExceptionが投げられるときには、CurrencyManager.Refresh()でデータを更新します。c# - Datagridview error System.IndexOutOfRangeException: Index 0 does not have a value - Stack Overflow
CurrencyManager currencyManager = (CurrencyManager)dataGridView.BindingContext[dataGridView.DataSource]; currencyManager.Refresh();CurrencyManager.Refresh メソッド (System.Windows.Forms) | Microsoft Learn
すべての列を表します。ただし行ヘッダーを含む列は除きます。DataGridViewColumnCollection クラス (System.Windows.Forms) | Microsoft Learn
個々の列はItem[]プロパティから取得できます。文字列で指定したときはDataGridViewColumn.Nameが対象となり、該当する列がなければnullが返されます。一方で数値で指定したときに範囲外ならば、ArgumentOutOfRangeException例外が投げられます。
現在アクティブなセル (DataGridViewCell) を表します。これに設定するとこのセルが表示されるようにスクロールされ、フォーカスされます。また同時に選択された状態となるため、それが不要ならばSelectedをfalseとするか、SetCurrentCellAddressCore()で現在のセルを設定するようにします。
これにnullを設定することでフォーカスを表す四角形を一時的に除去できますが、コントロールがフォーカスを得たときこれがnullならば、これにFirstDisplayedCellの値が自動的に設定されます。
セルの選択方法を設定できます。
| 列挙子 | 数値 | 選択方法 |
|---|---|---|
| CellSelect | 0 | つねにセルごと |
| FullRowSelect | 1 | つねに行全体 ※2 |
| FullColumnSelect ※1 | 2 | つねに列全体 |
| RowHeaderSelect | 3 | 行のヘッダーセルがクリックされたならば行全体、セルがクリックされたならばセルごと [既定値] |
| ColumnHeaderSelect ※1 | 4 | 列のヘッダーセルがクリックされたならば列全体、セルがクリックされたならばセルごと |
このVerticalScrollingOffsetはHorizontalScrollingOffsetとは異なり、値を設定することはできません。DataGridView.VerticalScrollingOffset プロパティ (System.Windows.Forms) | Microsoft Learn
しかしinternalなプロパティであるVerticalOffsetに設定すれば、スクロールさせることは可能です。
Type type = typeof(DataGridView); PropertyInfo verticalOffset = type.GetProperty("VerticalOffset", BindingFlags.Instance | BindingFlags.NonPublic); verticalOffset.SetValue(dataGridView, newValue);How do I programmatically scroll a winforms datagridview control? - Stack Overflow
ただし、そもそも垂直方向にはピクセル単位でスクロールしないため、FirstDisplayedScrollingRowIndexを用いて行単位でスクロールさせるのが簡単です。
またマウスの中ボタンによる水平スクロールやオートスクロールに対応するには、独自に実装する必要があります。
これに設定するときに行を表示する領域が不足していると、「行を表示する場所がありません。(No room is available to display rows.)」としてInvalidOperationExceptionが投げられます。FirstDisplayedScrollingRowIndex - DataGridView.cs
設定値が0未満またはRowCount以上ならば、「指定された引数は、有効な値の範囲内にありません。」としてArgumentOutOfRangeExceptionが投げられます。
コントロールの表示領域を表す四角形であり、ClientRectangleからスクロールバーの領域を除いた領域に一致します。DisplayRectangle - DataGridView.cs
表示領域全体ではなく、個別の列や行の領域は
で得られます。また条件を満たす列や行の累積した幅や高さは
で得られます。
ユーザーがセルのテキストをクリップボードへコピー可能か、そしてそのとき行や列のヘッダーを含めるかどうかを設定できます。コピーする内容の変更や、クリップボードからのコピーなどを実現するには、独自に実装する必要があります。
| 列挙子 | 数値 | |
|---|---|---|
| Disable | 0 | クリップボードへのコピーは無効 |
| EnableWithAutoHeaderText | 1 | 選択されているセルのテキストの値はクリップボードへコピーできる。ヘッダーテキストは、SelectionModeがRowHeaderSelectまたはColumnHeaderSelectであり、ヘッダーが選択されているとき含まれる [既定値] |
| EnableWithoutHeaderText | 2 | 選択されているセルのテキストの値はクリップボードへコピーできる。ヘッダーテキストは、含まれない |
| EnableAlwaysIncludeHeaderText | 3 | 選択されているセルのテキストの値はクリップボードへコピーできる。ヘッダーテキストは、つねに含まれる |
現在の行 (CurrentRow) には、それを示すグリフが表示されます。これを表示しない方法は提供されていないため、RowHeadersVisibleをfalseとして行ヘッダーを非表示にするか、オーナー描画でグリフを描画しないようにします。winforms - .NET DataGridView: Remove "current row" black triangle - Stack Overflow
| メソッド | 機能 |
|---|---|
| Sort(DataGridViewColumn, ListSortDirection) | 内容を並べ替えられる |
| ProcessDataGridViewKey(KeyEventArgs) | DataGridView内の移動に使用されるキーの処理を変更できる |
| ProcessDialogKey(Keys) | 編集モードでのキー入力や、修飾キーの処理を変更できる |
| HitTest(Int32, Int32) | 座標に対する列や行のインデックスの情報を得られる |
| ISupportInitialize.BeginInit() | 初期化が開始されていることを、オブジェクトに通知できる |
| DisplayedColumnCount(Boolean) | ユーザーに表示されている、列の数を得られる |
| DisplayedRowCount(Boolean) | ユーザーに表示されている、行の数を得られる DisplayedRowCount - DataGridViewMethods.cs |
| GetCellCount(DataGridViewElementStates) | 条件に合う、セルの数を得られる |
| BeginEdit(Boolean) | 現在のセルを、編集モードにできる。現在のセルがReadOnlyまたはEditTypeがnullならば、falseが返される |
| CancelEdit() | 現在のセルの編集モードをキャンセルして、変更を破棄できる |
| UpdateCellValue(Int32, Int32) | 指定位置のセルを新しい値で更新できる。自動サイズモード (automatic sizing modes) が適用される。セルの再描画が必要なだけならば、InvalidateCell()を呼ぶ |
| InvalidateCell(Int32, Int32) | 指定位置のセルを無効化して、 内部ではセルの描画位置を取得してControl.Invalidate()を呼ぶだけのため、描画は強制されない InvalidateCell - DataGridViewMethods.cs |
| InvalidateColumn(Int32) | 指定位置の列を無効化して、 |
| InvalidateRow(Int32) | 指定位置の行を無効化して、 |
| GetCellDisplayRectangle(Int32, Int32, Boolean) | 指定のセルの表示領域を得られる。インデックスに-1を指定して、行ヘッダーや列ヘッダーのセルを対象とできる |
| GetColumnDisplayRectangle(Int32, Boolean) | 指定の列の表示領域を得られる。指定できる列インデックスは0以上。返される領域のX座標は行ヘッダーの左端が基準であり、HorizontalScrollingOffsetを考慮しない表示上の位置 |
| GetRowDisplayRectangle(Int32, Boolean) | 指定の行の表示領域を得られる。指定できる行インデックスは0以上。第2引数にtrueを渡すと表示されている領域のみ、さもなくば行全体が返される。一部も表示されていなければRectangle.Emptyが返される GetRowDisplayRectangle - DataGridViewMethods.cs |
| SelectAll() | すべてのセルを選択できる |
| ClearSelection() | 選択されているセルの、選択を解除できる |
現在のセルの編集操作をコミットし、終了させられます。DataGridView.EndEdit メソッド (System.Windows.Forms) | Microsoft Learn
DataGridViewDataErrorContextsを省略すると、既定のエラー コンテキストとしてParsing | Commitが適用されます。EndEdit() - DataGridView.EndEdit Method (System.Windows.Forms) | Microsoft Learn
EditModeがEditOnEnterならば、CommitEdit()を呼び出すことと同じです。EndEdit - DataGridViewMethods.cs
列を指定して、昇順または降順に並べ替えられます。
public virtual void Sort (
System.Windows.Forms.DataGridViewColumn dataGridViewColumn,
System.ComponentModel.ListSortDirection direction
);
Sort(DataGridViewColumn, ListSortDirection) - DataGridView.Sort メソッド (System.Windows.Forms) | Microsoft Learn
このメソッドは存在している行を並べ替えるものであり、これの呼び出し後に追加した行には適用されません。
個々のDataGridViewCell.Valueに異なる型のインスタンスを設定している場合、既定の方法で並べ替えるとComparer.Compare()でArgumentException例外が発生することがあります。
並べ替えに対応しているDataSourceが設定されているならば、その機能を使用しても並べ替えられます。そのようなときにこのメソッドを用いるには制約があります。
DataGridViewColumn.SortModeは既定でAutomaticとなっており、ユーザーは任意の列ヘッダーをクリックすることで並べ替えできます。よってこのメソッドが必要なのは、並べ替えを独自に実装している場合です。
このメソッドはUIスレッドで処理されるため、多数の行があるとUIの応答が停止します。それが問題となるときはBindingSourceにバインドし、RaiseListChangedEventsをfalseとすると別スレッドで処理できます。
DataSourceでバインドしているならば、それの並べ替えを無効にすることで解除できます。.NET / WinForms - Clear a Sort on a DataGridView - Stack Overflow
DataTable table = (DataTable)dataGridView.DataSource; DataView view = table.DefaultView; view.Sort = "";
BindingSource source = (BindingSource)dataGridView.DataSource;
source.RemoveSort(); // source.Sort = null; としても同じ
Sort()では1つの列しか指定できないため、複数の列の値を考慮して並べ替えるにはSort(IComparer)で並べ替え方法を指定するか、DataSourceにバインドしているならばそれが備える並べ替えの機能を用います。c# - how to sort a datagridview by 2 columns - Stack Overflow
Sort()を呼ぶか既定の方法で並べ替えられると、現在アクティブな行と列のインデックスが維持され、アクティブなセルと選択は失われます。これを選択を維持するようにするにはSortModeをProgrammaticとして既定の並べ替えを無効にして、並べ替え前にその情報を保存しておき、並べ替え後に選択します。
次の例ではDataSourceが設定され、SelectionModeがFullRowSelectであると仮定しています。
private void dataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
// 現在のセルを保持
int prevColumnIndex = dataGridView.CurrentCell.ColumnIndex;
object prevItem = dataGridView.CurrentCell.OwningRow.DataBoundItem;
// 選択を保持
HashSet<object> selectedItems = new HashSet<object>(dataGridView.SelectedRows.Count);
foreach (DataGridViewRow row in dataGridView.SelectedRows)
{
selectedItems.Add(row.DataBoundItem);
}
ListSortDirection direction;
if (dataGridView.SortedColumn != null && dataGridView.SortedColumn.Index == e.ColumnIndex
&& dataGridView.SortOrder == SortOrder.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
direction = ListSortDirection.Ascending;
}
// 並べ替える
dataGridView.Sort(dataGridView.Columns[e.ColumnIndex], direction);
foreach (DataGridViewRow row in dataGridView.Rows)
{
// 現在のセルを復元
if (object.ReferenceEquals(prevItem, row.DataBoundItem))
{
dataGridView.CurrentCell = row.Cells[prevColumnIndex];
}
// 選択を復元
if (selectedItems.Remove(row.DataBoundItem))
{
row.Selected = true;
}
}
}
移動に使用されるキーを独自に処理することで、既定の処理を変更できます。
protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
switch(e.KeyData)
{
case Keys.Tab: // Tabキー
return base.ProcessDownKey(e.KeyData); // ↓キーの処理を実行する
default:
return base.ProcessDataGridViewKey(e);
}
}
このメソッドは、キー入力によって現在のセルが移動するときに呼び出されます。たとえば編集モードで→キーが押されたとき、テキスト間でキャレットが移動するだけならば呼ばれませんが、テキストの末尾で押されると次のセルへの移動となるため、そのタイミングで呼ばれます。
キーを処理するメソッドとしてProcessDownKey()やProcessEndKey()などが用意されていますが、これらのメソッドが共通して取るKeys列挙型はShiftやCtrlといった修飾キーの状態を調べることに使用されるだけで、それ以外のキーの指定は考慮されません。ProcessDownKey - DataGridViewMethods.cs
ProcessZeroKey()のような特定のキーを対象としたメソッドは、Ctrl+0のような既定のショートカットキーを処理するために用意されています。ProcessZeroKey - datagridview.processzero
キー入力に対する既定の処理は、DataGridView コントロールの既定のキーボードおよびマウス処理 - Windows Forms .NET Framework | Microsoft Learnで一覧できます。
Shift+Enterなど一部のキーは編集モードであるか否かによってProcessDataGridViewKey()やProcessDialogKey()で処理されます。これをそのモードにかかわらず処理するにはProcessCmdKey()を用います。
座標に対する列や行のインデックスの情報を得られます。
public System.Windows.Forms.DataGridView.HitTestInfo HitTest (
int x,
int y
);
DataGridView.HitTest(Int32, Int32) メソッド (System.Windows.Forms) | Microsoft Learn
private void dataGridView_MouseDown(object sender, MouseEventArgs e)
{
DataGridView.HitTestInfo hitTestInfo = dataGridView.HitTest(e.X, e.Y);
if (hitTestInfo.Type == DataGridViewHitTestType.Cell)
{
Debug.Write("Row:{0} Column:{1}",
hitTestInfo.RowIndex,
hitTestInfo.ColumnIndex);
}
}
DataGridView内の種類を表すHitTestInfo.Typeプロパティからは基本的な情報しか得られませんが、より詳細な情報はinternalな型であるDataGridViewHitTestTypeInternalから得られます。c# - How to detect if a MouseDown is over Row Resize Area - Stack Overflow
internal enum DataGridViewHitTestTypeInternal
{
None, // 0
Cell, // 1
ColumnHeader, // 2
RowHeader, // 3
ColumnResizeLeft, // 4
ColumnResizeRight, // 5
RowResizeTop, // 6
RowResizeBottom, // 7
FirstColumnHeaderLeft, // 8
TopLeftHeader, // 9
TopLeftHeaderResizeLeft, // 10
TopLeftHeaderResizeRight, // 11
TopLeftHeaderResizeTop, // 12
TopLeftHeaderResizeBottom, // 13
ColumnHeadersResizeBottom, // 14
ColumnHeadersResizeTop, // 15
RowHeadersResizeRight, // 16
RowHeadersResizeLeft, // 17
ColumnHeaderLeft, // 18
ColumnHeaderRight // 19
}
private void dataGridView_MouseDown(object sender, MouseEventArgs e)
{
HitTestInfo hitTestInfo = dataGridView.HitTest(e.X, e.Y);
System.Reflection.FieldInfo fieldInfo = typeof(HitTestInfo).GetField("typeInternal", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
DataGridViewHitTestTypeInternal hitTestType = (DataGridViewHitTestTypeInternal)fieldInfo.GetValue(hitTestInfo);
}
DataGridViewHitTestTypeInternal - DataGridView.cs
HitTestInfo - DataGridViewHitTestInfo.cs
アクティブなセルを設定できます。CurrentCellへの設定とは異なり、このセルが表示されるようにスクロールしたり、他の選択が解除されたりしません。
protected virtual bool SetCurrentCellAddressCore (
int columnIndex,
int rowIndex,
bool setAnchorCellAddress, // Shiftキーで複数選択するためのアンカー セル (anchor cell) とするならば、true
bool validateCurrentCell, // 以前のCurrentCellの値の検証に失敗したならば変更を取り消すならば、true
bool throughMouseClick // マウス クリックの結果として設定するならば、true
);
DataGridView.SetCurrentCellAddressCore メソッド (System.Windows.Forms) | Microsoft Learn
CurrentCellを設定するときは、内部ではこのメソッドによりアクティブなセルが設定されます。
ClearSelection(value.ColumnIndex, value.RowIndex, true /*selectExceptionElement*/);
if (!SetCurrentCellAddressCore(value.ColumnIndex, value.RowIndex, true, false, false))
{
throw new InvalidOperationException(SR.GetString(SR.DataGridView_CellChangeCannotBeCommittedOrAborted));
}
CurrentCell - DataGridView.cs
設定に成功するとtrueが返されます。
セルの選択状態を設定できます。
protected virtual void SetSelectedCellCore (
int columnIndex,
int rowIndex,
bool selected // 選択するならtrue、解除するならfalse
);
DataGridView.SetSelectedCellCore(Int32, Int32, Boolean) メソッド (System.Windows.Forms) | Microsoft Learn
選択するときには、SelectionModeやMultiSelectは考慮されません。 Remarks - DataGridView.SetSelectedCellCore(Int32, Int32, Boolean) Method (System.Windows.Forms) | Microsoft Learn SetSelectedCellCore - DataGridViewMethods.cs
DataGridViewCell.Selectedプロパティに設定するときは、内部でこのメソッドが呼ばれています。Selected - DataGridViewCell.cs
セルではなく列を対象とするならばSetSelectedColumnCore()、行ならばSetSelectedRowCore()を用います。
選択したときに他の選択を解除したいならば、第3引数をtrueとしてClearSelection(Int32, Int32, Boolean)を呼びます。SelectionModeがFullRowSelectやFullColumnSelectのときは列や行の指定は意味をなしませんが、範囲外の値を指定するとArgumentOutOfRangeExceptionが投げられます。
条件に合うセルの数を得られます。
public int GetCellCount (System.Windows.Forms.DataGridViewElementStates includeFilter);DataGridView.GetCellCount(DataGridViewElementStates) メソッド (System.Windows.Forms) | Microsoft Learn
条件のincludeFilterには、DataGridViewElementStatesの値を指定できます。
セルではなく行や列の数は、
で得られます。
選択されているセルの数を効率的に取得するには、このメソッドを用います。選択したセル、行、列のコレクションの効率的な使用 - DataGridView コントロールの拡大縮小に関するベスト プラクティス - Windows Forms .NET Framework | Microsoft Learn
つまりdataGridView.SelectedCells.Countではなく、dataGridView.GetCellCount(DataGridViewElementStates.Selected)とします。しかしこれはセルの数を得るためだけにSelectedCellsを介すのが非効率なだけであり、選択されているセルの情報も必要ならばSelectedCellsをローカルで保持しておき、それのCountプロパティから数を得るようにします。
SelectedCells - DataGridView.cs
Count - DataGridViewSelectedCellCollection.cs
GetCellCount - DataGridViewMethods.cs
なおすべてのセルが選択されているかどうかは、AreAllCellsSelected()で確認できます。
スクリーンに表示されている行の数はdataGridView.Rows.GetRowCount(DataGridViewElementStates.Displayed)としても得られますが、それ専用のdataGridView.DisplayedRowCount(true)の方が効率的です。同様に列はDisplayedColumnCount()で得られます。
指定のセルが範囲外だと「指定された引数は、有効な値の範囲内にありません。(Specified argument out of the range of valid values.)」として、ArgumentOutOfRangeExceptionが投げられます。
初期化が開始されていることを、オブジェクトに通知できます。これは次のように実装されています。
void ISupportInitialize.BeginInit()
{
if (this.dataGridViewState2[DATAGRIDVIEWSTATE2_initializing])
{
throw new InvalidOperationException(SR.GetString(SR.DataGridViewBeginInit));
}
this.dataGridViewState2[DATAGRIDVIEWSTATE2_initializing] = true;
}
ISupportInitialize.BeginInit() - DataGridView.cs
ISupportInitialize.BeginInit メソッド (System.ComponentModel) | Microsoft Learn
| 対象 | メソッド | 機能 | 対応する自動調整のプロパティ | |
|---|---|---|---|---|
| 列 | 高さ | AutoResizeColumnHeadersHeight() | 列ヘッダーの高さを調整できる | ColumnHeadersHeightSizeMode |
| 幅 | AutoResizeColumn(int) | 指定の列の幅を調整できる | AutoSizeColumnsMode | |
| AutoResizeColumns() | すべての列の幅を調整できる
ただしAutoSizeModeがDataGridViewAutoSizeColumnMode.Noneに設定されている列は調整されない |
|||
| 行 | 幅 | AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode) | 行ヘッダーの幅を調整できる | RowHeadersWidthSizeMode |
| 高さ | AutoResizeRow(int) | 指定の行の高さを調整できる | AutoSizeRowsMode | |
| AutoResizeRows() | すべての行の高さを調整できる
サイズ変更モードを省略すると、DataGridViewAutoSizeRowsMode.AllCellsが適用される AutoResizeRows - DataGridViewMethods.cs |
|||
AutoResizeColumnHeadersHeight()以外は、調整方法をそれぞれ異なる列挙型で指定します。
高さを調整するときWrapModeがTrueとなっていると、折り返されたテキストがすべて表示されるように高さが大きくなることがあります。
| 型 | イベント | 発生タイミング |
|---|---|---|
| EventHandler | DataSourceChanged | DataSourceプロパティの値が変更されたとき |
| DataGridViewDataErrorEventHandler | DataError | データの解析や検証で例外が投げられたとき |
| DataGridViewCellValidatingEventHandler | CellValidating | セルがフォーカスを失い、検証できるようになったとき |
| DataGridViewCellEventHandler | CellValidated | セルの検証が終わった後 |
| DataGridViewCellCancelEventHandler | RowValidating | 行が検証されているとき |
| DataGridViewCellEventHandler | RowValidated | 行の検証が終わった後 |
| DataGridViewCellEventHandler | CellValueChanged | セルの値が変更され、フォーカスが失われたとき。同じ値が設定された場合には発生しない |
| DataGridViewCellParsingEventHandler | CellParsing | セルの値が変更され、編集モードを離れたとき。同じ値が設定され、実際には変更されていない場合にも発生する |
| DataGridViewCellCancelEventHandler | CellBeginEdit | 選択されているセルの編集モードが開始するとき。これが発生した時点ではIsCurrentCellInEditModeはfalseであり、まだ編集中ではない |
| DataGridViewCellEventHandler | CellEndEdit | 選択されているセルの編集モードが停止されたとき。ESCにより編集がキャンセルされた場合にも発生する |
| DataGridViewRowEventHandler | DefaultValuesNeeded | ユーザーが新しい行を追加したとき |
| DataGridViewRowsAddedEventHandler | RowsAdded | 新しい行が追加された後 |
| DataGridViewRowsRemovedEventHandler | RowsRemoved | 1つまたは複数の行が削除されたとき |
| 型 | イベント | 発生タイミング |
|---|---|---|
| DataGridViewCellEventHandler | RowEnter | 行が入力フォーカスを得て、CurrentRowが更新される前
新しい行の情報は、DataGridViewCellEventArgs.RowIndexから得られる |
| DataGridViewCellEventHandler | CellEnter | 現在のセルが変更されたとき、またはコントロールがフォーカスを得たとき |
| DataGridViewCellMouseEventHandler | CellMouseMove | マウスポインタがセルの上を移動したとき。MouseMoveと異なり、セルが表示されていない部分では発生しない |
| 型 | イベント | 発生タイミング |
|---|---|---|
| EventHandler | SelectionChanged | 現在の選択が変更されるとき。選択されているセルは、SelectedCellsプロパティから得られる
CurrentCellの値を変更するとき、このイベントはCurrentCellChangedより前に発生し、その時点ではCurrentCellはまだ変更されていない。しかしユーザーによって選択が変更されたときは、CurrentCellは変更されている Remarks - DataGridView.SelectionChanged Event (System.Windows.Forms) | Microsoft Learn SelectionModeがFullRowSelectのとき、行内の他のセルを方向キーやクリックで選択したときはこのイベントは発生しないが、Tabで移動すると選択が変更されていないにもかかわらず発生する |
| EventHandler | CurrentCellChanged | CurrentCellプロパティが変更されるとき |
| DataGridViewCellEventHandler | CellClick | セルの任意の部分がクリックされたとき |
| DataGridViewCellMouseEventHandler | CellMouseClick | マウスでセルの任意の部分が、ユーザーによってクリックされたとき
このイベントのハンドラが受け取るDataGridViewCellMouseEventArgsはMouseEventArgsを継承するため、クリックされた位置やボタンの情報を得られる。ただしクリックの位置はセル相対のため、DataGridView内の相対位置は このイベントはOnMouseClick()でHitTest()が呼ばれた結果、セルの部分がクリックされたと判定されたときに発生する OnMouseClick - DataGridViewMethods.cs |
| DataGridViewCellMouseEventHandler | CellMouseDown | マウス ボタンでセルの境界内が、ユーザーによって押されたとき
境界内とはヘッダーを含むセルが表示されている範囲。セルはマウス ボタンが押されたときに選択されるため、それを変更するならばこのイベントに応じる |
| DataGridViewCellEventHandler | CellContentClick | セルのコンテンツがクリックされたとき。このときコンテンツとは、DataGridViewTextBoxCellのテキスト部分などが該当する。またそれにはDataGridViewHeaderCellも含まれるため、行や列のヘッダーセルも対象となる
DataGridViewButtonCellやDataGridViewCheckBoxCellにフォーカスがあるときに、Spaceキーが押されたときにも発生する |
| DataGridViewCellMouseEventHandler | ColumnHeaderMouseClick | 列ヘッダーがクリックされたとき。左上隅のセルでは発生しない |
| DataGridViewCellMouseEventHandler | RowHeaderMouseClick | 行ヘッダーがクリックされたとき。左上隅のセルでは発生しない |
| 型 | イベント | 発生タイミング |
|---|---|---|
| DataGridViewColumnEventHandler | ColumnWidthChanged | 列のWidthプロパティの値が変更されたとき。AutoSizeColumnsModeがNone以外に設定されていると、DataSourceやDataGridViewColumn.FillWeightが変更されるたびに発生する
Widthの既定値は100であり、この値に設定しても変更されていないため、このイベントは発生しない |
| DataGridViewRowEventHandler | RowHeightChanged | 行のHeightプロパティの値が変更されたとき |
| DataGridViewRowHeightInfoNeededEventHandler | RowHeightInfoNeeded | 行の高さについての情報が要求されたとき |
| DataGridViewRowHeightInfoPushedEventHandler | RowHeightInfoPushed | |
| EventHandler | ColumnHeadersHeightChanged | ColumnHeadersHeightプロパティの値が変更されたとき |
| EventHandler | RowHeadersWidthChanged | RowHeadersWidthプロパティの値が変更されたとき |
| 型 | イベント | 発生タイミング |
|---|---|---|
| DataGridViewColumnEventHandler | ColumnDividerWidthChanged | DividerWidthプロパティの値が変更されたとき |
| DataGridViewRowEventHandler | RowDividerHeightChanged | DividerHeightプロパティの値が変更されたとき |
| DataGridViewColumnDividerDoubleClickEventHandler | ColumnDividerDoubleClick | 列の間の境界線がダブルクリックされたとき。既定では、その列に適用されているInheritedAutoSizeModeに従い列の幅が調整される OnColumnDividerDoubleClick - DataGridViewMethods.cs
幅を明示的に調整するならばAutoResizeColumn()を呼び出して、e.Handledをtrueとする 注釈 - DataGridView.ColumnDividerDoubleClick イベント (System.Windows.Forms) | Microsoft Learn 行ヘッダーとの境界がダブルクリックされたときはe.ColumnIndexが-1となるため、AutoResizeRowHeadersWidth()を呼び出す。 |
| DataGridViewRowDividerDoubleClickEventHandler | RowDividerDoubleClick | 行の間の境界線がダブルクリックされたとき |
| 型 | イベント | 発生タイミング |
|---|---|---|
| DataGridViewCellContextMenuStripNeededEventHandler | CellContextMenuStripNeeded | セルのショートカットメニューが必要なとき。これのe.ContextMenuStripにnullを指定するか何も指定しなければ、ショートカットメニューの表示を抑制できる
このイベントはDataSourceが設定されているか、VirtualModeがtrueでなければ発生しない |
| DataGridViewRowContextMenuStripNeededEventHandler | RowContextMenuStripNeeded | 行のショートカットメニューが必要なとき
このイベントはDataSourceが設定されているか、VirtualModeがtrueでなければ発生しない |
| 型 | イベント | 発生タイミング |
|---|---|---|
| DataGridViewCellFormattingEventHandler | CellFormatting | セルの内容が、表示用に書式設定されなければならないとき |
| DataGridViewCellErrorTextNeededEventHandler | CellErrorTextNeeded | セルに関連付けられたエラー条件を表すテキストが必要なとき
このイベントはDataSourceが設定されているか、VirtualModeがtrueでなければ発生しない |
| DataGridViewRowErrorTextNeededEventHandler | RowErrorTextNeeded | 行のエラー テキストが必要なとき |
| DataGridViewCellToolTipTextNeededEventHandler | CellToolTipTextNeeded | セルのツールチップが必要なとき |
| DataGridViewRowPrePaintEventHandler | RowPrePaint | DataGridViewRowが描画される前
セルがクリックされたとき、MouseDownとMouseUpのタイミングで2回発生する。これはRowPostPaintも同様 |
| DataGridViewRowPostPaintEventHandler | RowPostPaint | DataGridViewRowが描画された後 |
| DataGridViewCellPaintingEventHandler | CellPainting | セルが描画される必要があるとき |
| 型 | イベント | 発生タイミング |
|---|---|---|
| EventHandler | Sorted | 並べ替え操作が完了したとき |
| DataGridViewSortCompareEventHandler | SortCompare | 並べ替え操作を実行するのに2つのセルの値を比較するとき |
データの解析や検証で例外が投げられたときに発生し、これを捕捉しなければ[DataGridView の既定のエラー ダイアログ]が表示されます。 DataGridView.DataError イベント (System.Windows.Forms) | Microsoft Learn Walkthrough: Handling errors that occur during data entry in DataGridView control - Windows Forms | Microsoft Learn
エラーの原因は、ハンドラに渡されるDataGridViewDataErrorEventArgs.Contextで得られます。
ハンドラの引数で渡されるDataGridViewCellValidatingEventArgsはCancelEventArgsを継承しており、検証に失敗したときはそれのCancelプロパティをtrueとすることで、確定を取り消し編集モードに戻せます。ただしこのイベントはこのコントロールが配置されたFormが閉じられるときにもセルのフォーカスが失われることで発生し、そこでCancelをtrueとするとForm.FormClosingのFormClosingEventArgs.Cancelもtrueとなり、フォームが閉じられなくなります。この問題に対処するにはフォームのAutoValidateをAutoValidate.Disableにして、フォームのフォーカスが失われたときに検証が発生しないようにします。
またはフォームが閉じられるときにCausesValidationをfalseにして、検証を無効にします。
protected override void WndProc(ref Message m)
{
const int WM_CLOSE = 0x0010;
if (m.Msg == WM_CLOSE)
{
dataGridView.CausesValidation = false;
}
base.WndProc(ref m);
}
c# - DataGridView CellValidated Event triggers when closing form - Stack Overflow
このイベントは「Note that this event occurs only when the user changes the height of a row.」としてユーザーが変更したときのみ発生するとされていますが、Remarks - DataGridView.RowHeightInfoPushed Event (System.Windows.Forms) | Microsoft Learn
実際にはAutoResizeRowInternal()でAutoSizeRowsModeがNoneのときにも発生するため、これを呼び出すAutoResizeRows()などからも発生します。
変更されたセルは、ハンドラに渡されるDataGridViewCellEventArgsから、
DataGridViewCell cell = dataGridView[e.RowIndex, e.ColumnIndex];
として取得できます。そのとき行が存在していないとe.RowIndexは-1となり、HeaderCellの値が変更されたときはe.ColumnIndexは-1となります。
データソースの変更によりセルの値が変更されたときは、このイベントは発生しません。
ハンドラを抜けるときに、
ならば、既定の型変換を用いてParseFormattedValue()で解析されます。
ハンドラで引数のDataGridViewCellFormattingEventArgs.Valueに値を設定したならば、同じく引数のFormattingAppliedをtrueとしてこれ以上の書式設定が不要であることを伝えます。それをfalseのままとすると、引数のCellStyleにより書式が適用されます。
FormattingAppliedをtrueとしたときにDesiredTypeと異なる型が設定されていると、「セルのフォーマットされた値に間違った型が指定されています。(Formatted value of the cell has a wrong type.)」としてFormatExceptionが投げられます。そのときDataErrorイベントにハンドラを登録していないと、既定のエラーダイアログで通知されます。
単純な書式ならば、DataGridViewColumn.DefaultCellStyleで指定しておくことで適用できます。
描画に関するイベントは、次の順で呼ばれます。
複数の列がある場合には、CellPaintingはその数だけくり返し呼ばれます。複数の行がある場合には、RowPrePaint、CellPainting、RowPostPaintの順でくり返し呼ばれます。そしてすべての行のイベントの後に、Paintが呼ばれます。
ハンドラの引数のDataGridViewRowPrePaintEventArgs.PaintPartsで描画するセルの部分を指定すると、その値がCellPaintingに渡されます。
private void dataGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
e.PaintParts &= ~DataGridViewPaintParts.ContentForeground;
}
描画時にはHorizontalScrollingOffsetを考慮しないと、水平スクロールされたときに描画位置がずれます。
private void dataGridView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
Rectangle rowBounds = e.RowBounds;
rowBounds.X = dataGridView.RowHeadersWidth; // 行ヘッダーの領域を除外する
rowBounds.Width = dataGridView.Columns.GetColumnsWidth(DataGridViewElementStates.Visible); // 表示可能な領域の幅を設定する
RectangleF clip = e.Graphics.ClipBounds; // 現在のクリッピング領域を保持する
// 描画する範囲のクリッピング領域を制限する
e.Graphics.SetClip(rowBounds);
Rectangle textArea = rowBounds;
textArea.X -= dataGridView.HorizontalScrollingOffset; // 水平方向にスクロールされている大きさ分、描画領域を移動する
String text = e.RowIndex.ToString();
DataGridViewCellStyle style = e.InheritedRowStyle;
// クリッピング領域が適用されるようにPreserveGraphicsClippingを指定する
TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.PreserveGraphicsClipping;
TextRenderer.DrawText(e.Graphics, text, style.Font, textArea, style.ForeColor, flags);
// クリッピング領域を元に戻す
e.Graphics.SetClip(clip);
}
セルの描画にオーナー描画が必要なときに呼ばれます。セルに値が設定されておらず、描画の必要がないときは呼ばれません。
private void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == -1 || e.RowIndex == -1)
{
// ヘッダーセルの描画
}
else
{
// 前景以外を描画する
e.Paint(e.CellBounds, e.PaintParts & ~DataGridViewPaintParts.ContentForeground);
if (e.Value != null)
{
// セルのテキストを赤で描画する
string text = (string)e.Value;
e.Graphics.DrawString(text, e.CellStyle.Font, Brushes.Red, e.CellBounds);
}
e.Handled = true;
}
}
| メソッド | 機能 |
|---|---|
| Paint(Rectangle, DataGridViewPaintParts) | 指定部分を描画できる |
| PaintContent(Rectangle) | ContentBackground | ContentForeground | ErrorIcon をDataGridViewPaintPartsの引数にして、Paint()を呼び出すのに等しい PaintContent - DataGridViewCellPaintingEventArgs.cs |
| PaintBackground(Rectangle, Boolean) | Background | Border、選択されているならばSelectionBackgroundも追加して、Paint()を呼び出すのに等しい PaintBackground - DataGridViewCellPaintingEventArgs.cs |
| 列挙子 | 値 | 内容 |
|---|---|---|
| None | 0 | 何も描画しない |
| Background | 1 | セルの背景を描画する |
| Border | 2 | セルの境界線を描画する |
| ContentBackground | 4 | セルの内容の背景を描画する (現在の行や並べ替えを示すグリフが含まれる) |
| ContentForeground | 8 | セルの内容の前景を描画する |
| ErrorIcon | 16 | セルのエラー アイコンを描画する |
| Focus | 32 | セルの周囲にフォーカスを示す四角形を描画する |
| SelectionBackground | 64 | セルが選択されたときに、セルの背景を描画する |
| All | 127 | セルのすべての部分を描画する |
マウス ポインタがセルに入ったときに発生します。DataGridView.CellMouseEnter イベント (System.Windows.Forms) | Microsoft Learn
ヘッダーセルにマウス ポインターが入ると、既定でそれがハイライトされます。
| クリックしたときの既定の動作 | ハイライトを無効にする方法 | |
|---|---|---|
| 行ヘッダー | クリックした行が選択される | SelectionModeをFullRowSelectとRowHeaderSelect以外にして、行が選択されないようにする |
| 列ヘッダー | クリックした列で並べ替えられる | DataGridViewColumn.SortModeをNotSortableとして、並べ替えを無効にする |
| 左上隅のヘッダー | すべてのセルが選択される | CellPaintingイベントで、セルの背景を描画しない |
左上隅のヘッダーをクリックすると既定ではすべてのセルが選択されますが、MultiSelectをfalseとしてセルを複数選択できないようにすると、クリックしても何も起きません。このときクリックに応答しないことを示すには、CellPaintingイベントでセルの背景をつねに同色で描画するようにして、セルにマウス ポインターが入ってもハイライトしないようにします。
private void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == -1 && e.RowIndex == -1)
{
using (Brush brush = new SolidBrush(dataGridView.ColumnHeadersDefaultCellStyle.BackColor))
{
e.Graphics.FillRectangle(brush, e.ClipBounds);
}
e.Paint(e.ClipBounds, e.PaintParts & ~DataGridViewPaintParts.Background);
e.Handled = true;
}
}
追加された行を個別に特定するには、RowIndexを基点としてRowCountの数だけループさせます。c# - DataGridView row added event - Stack Overflow
private void dataGridView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
for (int i = 0; i < e.RowCount; i++)
{
DataGridViewRow row = dataGridView.Rows[e.RowIndex + i];
}
}
セルの編集用のコントロールが表示されるときに発生します。このイベントを処理することで、セルが編集モードに入るときに編集用のコントロール (EditingControl) を操作できます。DataGridViewでセルの編集に使われているテキストボックスを取得する - .NET Tips (VB.NET,C#...)
DataGridViewは編集と編集の間にセルの型が変更されなければ、編集用のコントロールを再利用します。そのためハンドラでControlを操作するときは、イベントのたびにControlに必要な設定をします。Remarks - DataGridView.EditingControlShowing Event (System.Windows.Forms) | Microsoft Learn
Per-Monitor V2 によってディスプレイによってDPIが異なるとき、TextBoxにAutoCompleteを設定しそのコントロールが他のセルで再利用されると、「ウィンドウのハンドルを作成中にエラーが発生しました。」としてWin32Exceptionが投げられます。 c# - Winforms application throws Win32Exception if marked as DPI aware and used with multiple monitors - Stack Overflow
private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
TextBox textBox = e.Control as TextBox;
if (textBox.AutoCompleteMode == AutoCompleteMode.None)
{
textBox.AutoCompleteMode = AutoCompleteMode.Suggest;
textBox.AutoCompleteSource = AutoCompleteSource.CustomSource;
textBox.AutoCompleteCustomSource.AddRange(new[] { "a1", "a2", "a3" });
}
if (dataGridView.DeviceDpi != textBox.DeviceDpi)
{
// このようにDPIが異なる状態でtextBoxが表示されるとき、そのCreateHandle()でWin32Exceptionが投げられる
}
}
この問題はコントロールが再利用されないように、編集が終了したときにそれを破棄することで解決できます。c# - DataGridViewComboBoxColumn - value lags for a split second - Stack Overflow
private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView.DeviceDpi != dataGridView.EditingPanel.DeviceDpi)
{
FieldInfo latestEditingControl = typeof(DataGridView).GetField("latestEditingControl", BindingFlags.NonPublic | BindingFlags.Instance);
((Control)latestEditingControl.GetValue(dataGridView)).Dispose();
latestEditingControl.SetValue(dataGridView, null);
}
}