DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

DataGridViewでセルが編集中の時にキーイベントを捕捉する

注意:DataGridViewコントロールは、.NET Framework 2.0で新しく追加されました。

DataGridViewのキーイベント(KeyDown、KeyUp、KeyPress、PreviewKeyDown)は、セルが編集中の場合は、発生しません。なぜなら、セルの編集にはテキストボックスが使用されているからです。よって、セルを編集中のときのキーイベントを捕捉するには、このテキストボックスのキーイベントを捕捉します。

セルの編集に使用されているテキストボックスのイベントを捕捉するには、こちらで紹介した方法により、EditingControlShowingイベントハンドラで編集に使用しているテキストボックスを取得し、AddHandlerでイベントハンドラを追加します。

ただし、同じイベントハンドラが同じテキストボックスのイベントに何回も追加されないように注意する必要があります。そのためには、フラッグを立ててイベントハンドラを追加したことを覚えておくか、適当なタイミング(EditingControlShowingイベントハンドラの先頭や、CellEndEditイベントハンドラ)でイベントハンドラを削除するようにします。

以下に示す例では、「TextBoxに数字しか入力できないようにする」で紹介したように、KeyPressイベントを使ってテキストボックスに数字しか入力できないようにしています。この例では、EditingControlShowingイベントハンドラでKeyPressイベントハンドラを削除しています(CellEndEditイベントハンドラで削除する例は、こちらで紹介しています)。

VB.NET
コードを隠すコードを選択
'EditingControlShowingイベントハンドラ
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, _
        ByVal e As DataGridViewEditingControlShowingEventArgs) _
        Handles DataGridView1.EditingControlShowing
    '表示されているコントロールがDataGridViewTextBoxEditingControlか調べる
    If TypeOf e.Control Is DataGridViewTextBoxEditingControl Then
        Dim dgv As DataGridView = CType(sender, DataGridView)

        '編集のために表示されているコントロールを取得
        Dim tb As DataGridViewTextBoxEditingControl = _
            CType(e.Control, DataGridViewTextBoxEditingControl)

        'イベントハンドラを削除
        RemoveHandler tb.KeyPress, AddressOf dataGridViewTextBox_KeyPress

        '該当する列か調べる
        If dgv.CurrentCell.OwningColumn.Name = "Column1" Then
            'KeyPressイベントハンドラを追加
            AddHandler tb.KeyPress, AddressOf dataGridViewTextBox_KeyPress
        End If
    End If
End Sub

'DataGridViewに表示されているテキストボックスのKeyPressイベントハンドラ
Private Sub dataGridViewTextBox_KeyPress(ByVal sender As Object, _
        ByVal e As KeyPressEventArgs)
    '数字しか入力できないようにする
    If e.KeyChar < "0"c Or e.KeyChar > "9"c Then
        e.Handled = True
    End If
End Sub
C#
コードを隠すコードを選択
//EditingControlShowingイベントハンドラ
private void DataGridView1_EditingControlShowing(object sender,
    DataGridViewEditingControlShowingEventArgs e)
{
    //表示されているコントロールがDataGridViewTextBoxEditingControlか調べる
    if (e.Control is DataGridViewTextBoxEditingControl)
    {
        DataGridView dgv = (DataGridView)sender;

        //編集のために表示されているコントロールを取得
        DataGridViewTextBoxEditingControl tb =
            (DataGridViewTextBoxEditingControl)e.Control;

        //イベントハンドラを削除
        tb.KeyPress -=
            new KeyPressEventHandler(dataGridViewTextBox_KeyPress);

        //該当する列か調べる
        if (dgv.CurrentCell.OwningColumn.Name == "Column1")
        {
            //KeyPressイベントハンドラを追加
            tb.KeyPress +=
                new KeyPressEventHandler(dataGridViewTextBox_KeyPress);
        }
    }
}

//DataGridViewに表示されているテキストボックスのKeyPressイベントハンドラ
private void dataGridViewTextBox_KeyPress(object sender,
    KeyPressEventArgs e)
{
    //数字しか入力できないようにする
    if (e.KeyChar < '0' || e.KeyChar > '9')
    {
        e.Handled = true;
    }
}

DataGridViewでセルの編集に使われているその他のコントロールのイベントを捕捉する

上記と同じ方法により、DataGridViewで編集に使用される別のコントロールのイベントを捕捉することもできます。しかしこのようなコントロールは、こちらで指摘したように、カスタム列を除けば、DataGridViewTextBoxEditingControlとDataGridViewComboBoxEditingControlコントロールだけです。

DataGridViewでセルの編集に使われているコンボボックスのイベントを捕捉する例は、こちらで紹介しています。

  • 履歴:
  • 2010/6/29 VB.NETのコードで、dataGridViewTextBox_KeyPressに「Handles DataGridView1.KeyPress」が付いていたのを修正。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。