DataGridView

DataGridViewは、DataGridを拡張したクラスです。Differences Between the Windows Forms DataGridView and DataGrid Controls | Microsoft Learn

クラス階層

  • System.Object
    • System.MarshalByRefObject
      • System.ComponentModel.Component
        • System.Windows.Forms.Control
          • System.Windows.Forms.DataGridView

プロパティ

プロパティ 内容
object DataSource データソース
string DataMember データソースに複数のテーブルまたはリストが含まれるときに、対象とするそれの名前。単一のテーブルまたはリストならば、指定する必要はない
DataGridViewColumnCollection Columns すべての列 (DataGridViewColumn) を含むコレクション。ただし行ヘッダーを含む列は除く
DataGridViewRowCollection Rows すべての行 (DataGridViewRow) を含むコレクション。ただし列ヘッダーを含む行は除く
DataGridViewCell Item[Int32, Int32] 指定の列の、指定の行にあるセル
DataGridViewHeaderCell TopLeftHeaderCell 左上隅にあるヘッダーセル。MultiSelectがtrueのとき、これをクリックするとSelectAll()が呼ばれる OnTopLeftHeaderMouseDown - DataGridViewMethods.cs
int ColumnCount 表示されている列の数。これに設定すると、その数になるように列が削除または追加される

これから取得するのはColumns.Countと等しい ColumnCount - DataGridView.cs

ユーザーに表示されている列の数は、DisplayedColumnCount()で得られる

int RowCount 表示されている行の数。これに設定すると、その数になるように行が削除または追加される

これから取得するのはRows.Countと等しい RowCount - DataGridView.cs

ユーザーに表示されている行の数は、DisplayedRowCount()で得られる

bool IsCurrentCellDirty trueならば、現在のセルがコミット (確定) されていないデータを含む
bool IsCurrentRowDirty trueならば、現在の行がコミット (確定) されていないデータを含む
bool IsCurrentCellInEditMode trueならば、現在のセルが編集中
Control EditingControl セルが編集モードのとき、そのセルでホストされているコントロール
int HorizontalScrollingOffset 水平にスクロールされているピクセル数
int VerticalScrollingOffset 垂直にスクロールされているピクセル数
プロパティ 内容
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 並べ替えの列。読取専用。設定するにはSort()を呼ぶ。並べ替えを独自に実装しているならば、この値は意味をなさない
SortOrder SortOrder 並べ替えの順。読取専用
プロパティ 内容 既定値
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ならば、エラーを含むときに行ヘッダーにエラーグリフ (error glyphs) を表示する (グリフを表示する領域が不足するならば、グリフは表示されない) true
bool ColumnHeadersVisible trueならば、列ヘッダーを表示する true
bool RowHeadersVisible trueならば、行ヘッダーを格納している列を表示する true
bool StandardTab trueならば、Tabキーでタブ オーダーの次のコントロールにフォーカスが移動する。さもなくば次のセルのフォーカスが移動する false
bool VirtualMode trueならば、独自のデータ管理操作を提供している false
       
プロパティ - DataGridView クラス (System.Windows.Forms) | Microsoft Learn
スタイル関連
区分 プロパティ 内容
既定値 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
※1 EnableHeadersVisualStylesをfalseとしないと、視覚スタイルで設定されているスタイルは適用されない

DataSource

以下のインターフェイスを実装するオブジェクトを、データソースに指定できます。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となります。

IndexOutOfRangeException

DataSourceへ設定後にそれへアクセスしたときに、CurrencyManager.get_Item(Int32 index)でIndexOutOfRangeExceptionが投げられるときには、CurrencyManager.Refresh()でデータを更新します。c# - Datagridview error System.IndexOutOfRangeException: Index 0 does not have a value - Stack Overflow

((CurrencyManager)dataGridView.BindingContext[list]).Refresh();
CurrencyManager.Refresh メソッド (System.Windows.Forms) | Microsoft Learn

Columns

すべての列を表します。ただし行ヘッダーを含む列は除きます。DataGridViewColumnCollection クラス (System.Windows.Forms) | Microsoft Learn

個々の列はItem[]プロパティから取得できます。文字列で指定したときはDataGridViewColumn.Nameが対象となり、該当する列がなければnullが返されます。一方で数値で指定したときに範囲外ならば、ArgumentOutOfRangeException例外が投げられます。

CurrentCell

現在アクティブなセル (DataGridViewCell) を表します。これに設定するとこのセルが表示されるようにスクロールされ、フォーカスされます。また同時に選択された状態となるため、それが不要ならばSelectedをfalseとするか、SetCurrentCellAddressCore()で現在のセルを設定するようにします。

これにnullを設定することでフォーカスを表す四角形を一時的に除去できますが、コントロールがフォーカスを得たときこれがnullならば、これにFirstDisplayedCellの値が自動的に設定されます。

SelectionMode

セルの選択方法を設定できます。

DataGridViewSelectionMode 列挙型
列挙子 数値 選択方法
CellSelect 0 つねにセルごと
FullRowSelect 1 つねに行全体 ※2
FullColumnSelect ※1 2 つねに列全体
RowHeaderSelect 3 行のヘッダーセルがクリックされたならば行全体、セルがクリックされたならばセルごと [既定値]
ColumnHeaderSelect ※1 4 列のヘッダーセルがクリックされたならば列全体、セルがクリックされたならばセルごと
※1 SortModeがAutomaticのDataGridViewColumnが含まれていると、列全体を選択する設定にはできない
※2 .NET Framework 4.7.2以降、列ヘッダーの色で現在の列が識別できるようになった .NET 4.7.2 の Windows フォーム コントロールでのアクセシビリティの向上 - .NET Framework 4.7.1 から 4.7.2 への移行に関する変更の再ターゲット - .NET Framework | Microsoft Learn

VerticalScrollingOffset

この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を用いて行単位でスクロールさせるのが簡単です。

またマウスの中ボタンによる水平スクロールやオートスクロールに対応するには、独自に実装する必要があります。

FirstDisplayedScrollingRowIndex

これに設定するときに行を表示する領域が不足していると、「行を表示する場所がありません。(No room is available to display rows.)」としてInvalidOperationExceptionが投げられます。FirstDisplayedScrollingRowIndex - DataGridView.cs

ClipboardCopyMode

ユーザーがセルのテキストをクリップボードへコピー可能か、そしてそのとき行や列のヘッダーを含めるかどうかを設定できます。コピーする内容の変更や、クリップボードからのコピーなどを実現するには、独自に実装する必要があります。

DataGridViewClipboardCopyMode 列挙型
列挙子 数値  
Disable 0 クリップボードへのコピーは無効
EnableWithAutoHeaderText 1 選択されているセルのテキストの値はクリップボードへコピーできる。ヘッダーテキストは、SelectionModeがRowHeaderSelectまたはColumnHeaderSelectであり、ヘッダーが選択されているとき含まれる [既定値]
EnableWithoutHeaderText 2 選択されているセルのテキストの値はクリップボードへコピーできる。ヘッダーテキストは、含まれない
EnableAlwaysIncludeHeaderText 3 選択されているセルのテキストの値はクリップボードへコピーできる。ヘッダーテキストは、つねに含まれる
DataGridViewClipboardCopyMode Enum (System.Windows.Forms) | Microsoft Learn ※1 行全体がコピーされる設定となっていても、 DataGridViewRow.HeaderCell.Valueに文字列が設定されていなければ、ヘッダーの文字列はコピーされない。

RowHeadersVisible

現在の行 (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) ユーザーに表示されている、行の数を得られる
GetCellCount(DataGridViewElementStates) 条件に合う、セルの数を得られる
BeginEdit(Boolean) 現在のセルを、編集モードにできる
CancelEdit() 現在のセルの編集モードをキャンセルして、変更を破棄できる
UpdateCellValue(Int32, Int32) 指定位置のセルを新しい値で更新できる。自動サイズモード (automatic sizing modes) が適用される。セルの再描画が必要なだけならば、InvalidateCell()を呼ぶ
InvalidateCell(Int32, Int32) 指定位置のセルを無効化して、強制的に再描画させられる (forcing it to be repainted)

内部ではセルの描画位置を取得して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() 選択されているセルの、選択を解除できる
   
幅や高さの自動調整
対象 メソッド 機能
高さ AutoResizeColumnHeadersHeight() 列ヘッダーの高さを調整できる
AutoResizeColumn(int columnIndex) 指定の列の幅を調整できる
AutoResizeColumns() すべての列の幅を調整できる。ただしAutoSizeModeがDataGridViewAutoSizeColumnMode.Noneに設定されている列は調整されない
AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode) 行ヘッダーの幅を調整できる
高さ AutoResizeRow(int rowIndex) 指定の行の高さを調整できる
AutoResizeRows() すべての行の高さを調整できる

サイズ変更モードを省略すると、DataGridViewAutoSizeRowsMode.AllCellsが適用される AutoResizeRows - DataGridViewMethods.cs

メソッド - DataGridView クラス (System.Windows.Forms) | Microsoft Learn

EndEdit()

現在のセルの編集操作をコミットし、終了させられます。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

Sort()

列を指定して、昇順または降順に並べ替えられます。

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が設定されているならば、その機能を使用しても並べ替えられます。そのようなときにこのメソッドを用いるには制約があります

  • DataSourceが並べ替えに非対応だと「並び替えをサポートしていない IBindingList にバインドされた DataGridView コントロールを並べ替えることはできません。」としてInvalidOperationExceptionが投げられる。
  • バインドしていない列では並べ替えられない。並べ替えようとすると「データバインドされた DataGridView コントロールは、データバインドされた列でのみ並べ替えることができます。」としてArgumentExceptionが投げられる。このような場合には並べ替え用の列を追加して、それをバインドする。そしてその列に、対象の列を表示したい順に値を設定する。Programmatic Sorting - Column Sort Modes in the Windows Forms DataGridView Control | Microsoft Learn
  • 比較子を指定するオーバーロードSort(IComparer)は使用できない。呼び出すとInvalidOperationExceptionで失敗する。

DataGridViewColumn.SortModeは既定でAutomaticとなっており、ユーザーは任意の列ヘッダーをクリックすることで並べ替えできます。

並べ替えの解除

DataSourceでバインドしているならば、それの並べ替えを無効にすることで解除できます。.NET / WinForms - Clear a Sort on a DataGridView - Stack Overflow

DataTableにバインドしている場合
DataTable table = (DataTable)dataGridView.DataSource;
DataView view = table.DefaultView;
view.Sort = "";
BindingSourceにバインドしている場合
BindingSource source = (BindingSource)dataGridView.DataSource;
source.RemoveSort(); // source.Sort = null; としても同じ

ProcessDataGridViewKey()

移動に使用されるキーを独自に処理することで、既定の処理を変更できます。

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で一覧できます。

ProcessDialogKey()

Shift+Enterなど一部のキーは編集モードであるか否かによってProcessDataGridViewKey()やProcessDialogKey()で処理されます。これをそのモードに関わらず処理するにはProcessCmdKey()を用います。

HitTest()

座標に対する列や行のインデックスの情報を得られます。

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

SetCurrentCellAddressCore()

アクティブなセルを設定できます。

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を設定するときは、内部ではこのメソッドによりアクティブなセルが設定されます。CurrentCell - DataGridView.cs

設定に成功するとtrueが返されます。

SetSelectedCellCore()

セルの選択状態を設定できます。

protected virtual void SetSelectedCellCore (
    int columnIndex,
    int rowIndex,
    bool selected
    );
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

GetCellCount()

選択されているセルの数を効率的に取得するには、このメソッドを用います。選択したセル、行、列のコレクションの効率的な使用 - DataGridView コントロールの拡大縮小に関するベスト プラクティス - Windows Forms .NET Framework | Microsoft Learn

public int GetCellCount (System.Windows.Forms.DataGridViewElementStates includeFilter);
DataGridView.GetCellCount(DataGridViewElementStates) メソッド (System.Windows.Forms) | Microsoft Learn

つまりdataGridView.SelectedCells.Countではなく、dataGridView.GetCellCount(DataGridViewElementStates.Selected)とします。しかしこれはセルの数を得るためだけにSelectedCellsを介すのが非効率なだけであり、選択されているセルの情報も必要ならばSelectedCellsをローカルで保持しておき、それのCountプロパティから数を得るようにします。 SelectedCells - DataGridView.cs Count - DataGridViewSelectedCellCollection.cs GetCellCount - DataGridViewMethods.cs

すべてのセルが選択されているかどうかは、AreAllCellsSelected()で確認できます。

ところで行や列の数は、

で得られます。

InvalidateCell()

指定のセルが範囲外だと「指定された引数は、有効な値の範囲内にありません。(Specified argument out of the range of valid values.)」として、ArgumentOutOfRangeExceptionが投げられます。

ISupportInitialize.BeginInit()

初期化が開始されていることを、オブジェクトに通知できます。これは次のように実装されています。

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

イベント

セルの内容
イベント 発生タイミング
EventHandler DataSourceChanged DataSourceプロパティの値が変更されたとき
DataGridViewDataErrorEventHandler DataError データの解析や検証で例外が投げられたとき
DataGridViewCellValidatingEventHandler CellValidating セルがフォーカスを失い、検証できるようになったとき
DataGridViewCellEventHandler CellValidated セルの検証が終わった後
DataGridViewCellCancelEventHandler RowValidating 行が検証されているとき
DataGridViewCellEventHandler RowValidated 行の検証が終わった後
DataGridViewCellEventHandler CellValueChanged セルの値が変更され、フォーカスが失われたとき。同じ値が設定された場合には発生しない
DataGridViewCellParsingEventHandler CellParsing セルの値が変更され、編集モードを離れたとき。同じ値が設定され、実際には変更されていない場合にも発生する
DataGridViewCellCancelEventHandler CellBeginEdit 選択されているセルの編集モードが開始するとき
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内の相対位置はdataGridView.PointToClient(Control.MousePosition)で得る

このイベントはOnMouseClick()でHitTest()が呼ばれた結果、セルの部分がクリックされたと判定されたときに発生する OnMouseClick - DataGridViewMethods.cs

DataGridViewCellMouseEventHandler CellMouseDown マウス ボタンでセルの境界内が、ユーザーによって押されたとき

境界内とはヘッダーを含むセルが表示されている範囲。セルはマウス ボタンが押されたときに選択されるため、それを変更するならばこのイベントに応じる

DataGridViewCellEventHandler CellContentClick セルのコンテンツがクリックされたとき。このときコンテンツとは、DataGridViewTextBoxCellのテキスト部分などが該当する

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でなければ発生しない

DataGridViewCellToolTipTextNeededEventHandler CellToolTipTextNeeded セルのツールチップが必要なとき
DataGridViewRowPrePaintEventHandler RowPrePaint DataGridViewRowが描画される前

セルがクリックされたとき、MouseDownとMouseUpのタイミングで2回発生する。これはRowPostPaintも同様

DataGridViewRowPostPaintEventHandler RowPostPaint DataGridViewRowが描画された後
DataGridViewCellPaintingEventHandler CellPainting セルが描画される必要があるとき
     
イベント - DataGridView Class (System.Windows.Forms) | Microsoft Learn

DataError

データの解析や検証で例外が投げられたときに発生し、これを捕捉しなければ[DataGridView の既定のエラー ダイアログ]が表示されます。

Walkthrough: Handling errors that occur during data entry in DataGridView control - Windows Forms | Microsoft Learn

CellValidating

DataGridView.CellValidating イベント (System.Windows.Forms) | Microsoft Learn

ハンドラの引数で渡される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

CellValueChanged

変更されたセルは、ハンドラに渡されるDataGridViewCellEventArgsから、

DataGridViewCell cell = dataGridView[e.RowIndex, e.ColumnIndex];

として取得できます。そのとき行が存在していないとe.RowIndexは-1となり、HeaderCellの値が変更されたときはe.ColumnIndexは-1となります。

データソースの変更によりセルの値が変更されたときは、このイベントは発生しません。

CellParsing

ハンドラを抜けるときに、

  • ConvertEventArgs.Valueが、null
  • ConvertEventArgs.Valueの型が、不正確
  • DataGridViewCellParsingEventArgs.ParsingAppliedが、false

ならば、既定の型変換を用いてParseFormattedValue()で解析されます。

RowPrePaint

描画に関するイベントは、次の順で呼ばれます。

  1. RowPrePaint (列ヘッダーでは呼ばれない)
  2. CellPainting
  3. RowPostPaint (列ヘッダーでは呼ばれない)
  4. Paint

複数の列がある場合には、CellPaintingはその数だけくり返し呼ばれます。複数の行がある場合には、RowPrePaint、CellPainting、RowPostPaintの順でくり返し呼ばれます。そしてすべての行のイベントの後に、Paintが呼ばれます。

ハンドラの引数のDataGridViewRowPrePaintEventArgs.PaintPartsで描画するセルの部分を指定すると、その値がCellPaintingに渡されます。

private void dataGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
    e.PaintParts &= ~DataGridViewPaintParts.ContentForeground;
}

RowPostPaint

描画時には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);
}

CellPainting

セルの描画にオーナー描画が必要なときに呼ばれます。セルに値が設定されておらず、描画の必要がないときは呼ばれません。

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;
    }
}
DataGridViewCellPaintingEventArgsのメソッド
メソッド 機能
Paint(Rectangle, DataGridViewPaintParts) 指定部分を描画できる
PaintContent(Rectangle) ContentBackground | ContentForeground | ErrorIcon をDataGridViewPaintPartsの引数にして、Paint()を呼び出すのに等しい PaintContent - DataGridViewCellPaintingEventArgs.cs
PaintBackground(Rectangle, Boolean) Background | Border、選択されているならばSelectionBackgroundも追加して、Paint()を呼び出すのに等しい PaintBackground - DataGridViewCellPaintingEventArgs.cs
   

DataGridViewPaintParts列挙型

列挙子 内容
None 0 何も描画しない
Background 1 セルの背景を描画する
Border 2 セルの境界線を描画する
ContentBackground 4 セルの内容の背景を描画する (現在の行や並べ替えを示すグリフが含まれる)
ContentForeground 8 セルの内容の前景を描画する
ErrorIcon 16 セルのエラー アイコンを描画する
Focus 32 セルの周囲にフォーカスを示す四角形を描画する
SelectionBackground 64 セルが選択されたときに、セルの背景を描画する
All 127 セルのすべての部分を描画する
フィールド - DataGridViewPaintParts 列挙型 (System.Windows.Forms) | Microsoft Learn

CellMouseEnter

マウス ポインタがセルに入ったときに発生します。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;
    }
}

RowsAdded

追加された行を個別に特定するには、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];
    }
}

EditingControlShowing

DataGridViewは編集と編集の間にセルの型が変更されなければ、編集用のコントロールを再利用します。そのためハンドラでControlを操作するときは、イベントのたびにControlに必要な設定をします。Remarks - DataGridView.EditingControlShowing Event (System.Windows.Forms) | Microsoft Learn

DataGridViewでセルの編集に使われているテキストボックスを取得する - .NET Tips (VB.NET,C#...)

データソースとの結びつけ

たとえば、

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <data>
    <item1>A1</item1>
  </data>
  <data>
    <item1>B1</item1>
  </data>
</root>

というファイルsample.xmlが存在するとき、

DataSet dataSet = new DataSet();
dataSet.ReadXml("sample.xml");

dataGridView.AutoGenerateColumns = true;
dataGridView.DataSource = dataSet.Tables[0];

とすると、2つの項目がitem1という列に読み込まれます。Windowsフォームにおける「データ・バインディング」(1/3) - @IT 初音玲 (2010/11/16)

データソースと結びつけているとき、データソースの値を変更するとDataGridViewも更新され、逆にDataGridViewのセルの値を変更するとデータソースも更新されます。

階層化されているオブジェクト

リレーションシップなどでデータソースが階層化されているとき、下層のデータは処理対象となりません。この場合にはCellFormattingイベントを捕捉し、そこでDataGridViewCellFormattingEventArgs.Valueに表示したい内容を指定します。

データソースとして直接結びつけられていないデータを更新しても、DataGridViewの表示は更新されません。このような場合にはDataGridView.UpdateCellValue()で明示的に更新させます。

パフォーマンス

共有行 (Shared Rows)

Using Shared Rows - Best Practices for Scaling DataGridView Control - Windows Forms .NET Framework | Microsoft Learn

DataGridViewRowCollection.SharedRow()メソッドで取得したDataGridViewRowのIndexプロパティが-1ならば、その行は共有行です。

仮想モード (virtual mode)

Microsoft Learnから検索