web-dev-qa-db-ja.com

DataGridViewキーダウンイベントがC#で機能しない

セル内のテキストを編集しているときに、DataGridViewのkeydownイベントが機能しません。

データを保存するためにショートカットAlt + Sを割り当てています。セルが編集モードでない場合は機能しますが、以下のコードが編集モードの場合は機能しません。

private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
 {
    if (e.KeyData == (Keys.Alt | Keys.S))
    {
         //save data
    }
 }
19
Javed Akram

セルが編集モードにあるときはいつでも、そのホストされたコントロールは、それを含む親KeyDownではなく、DataGridViewイベントを受信して​​います。これが、セルが編集モードでないときはいつでも(セルが選択されていても)キーボードショートカットが機能する理由です。これは、DataGridViewコントロール自体がKeyDownイベントを受信するためです。ただし、編集モードの場合、セルに含まれる編集コントロールはイベントを受信して​​おり、カスタムハンドラルーチンがアタッチされていないため、何も起こりません。

標準のDataGridViewコントロールを微調整して、編集コミットを希望どおりに処理するのに時間がかかりすぎました。この現象を回避する最も簡単な方法はであることがわかりました。既存のDataGridViewコントロールをサブクラス化し、その ProcessCmdKey関数をオーバーライドします。ここに入力したカスタムコードは、編集モードであるかどうかに関係なく、DataGridViewの上でキーが押されるたびに実行されます。

たとえば、次のようなことができます。

class MyDataGridView : System.Windows.Forms.DataGridView
{
    protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
    {

        MessageBox.Show("Key Press Detected");

        if ((keyData == (Keys.Alt | Keys.S)))
        {
            //Save data
        }

        return base.ProcessCmdKey(ref msg, keyData);
    }
}

関連する、多少古い記事も参照してください: Visual C#を使用してコントロールのキーストロークをトラップする方法

21
Cody Gray

これを行う別の方法は、EditingControlShowingイベントを使用して、以下のようにイベント処理をカスタムイベントハンドラーにリダイレクトすることです。

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
 {
    if (e.Control is DataGridViewTextBoxEditingControl tb)
            {
                tb.KeyDown -= dataGridView1_KeyDown;
                tb.KeyDown += dataGridView1_KeyDown;
            }
 }

//then in your keydown event handler, execute your code
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
 {
    if (e.KeyData == (Keys.Alt | Keys.S))
    {
         //save data
    }
 }
14
user2054522

私が試した簡単な方法は次のとおりです。

  1. フォームのKeyPreviewプロパティをtrueに設定します。
  2. グリッドでKeyDownイベントをキャッチする代わりに、フォームでKeyDownイベントをキャッチします。

次のようにコーディングします。

Private Sub form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown

   If grd.Focused Then

      'Do your work

   End If

End Sub
3
Prashant Gupta

これは、EditingControlShowingが役立つことは事実ですが、Enterキーをキャッチしたい場合は役立ちません。その場合、次の方法を使用する必要があります。

 private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        if (e.Control is DataGridViewTextBoxEditingControl)
        {
            DataGridViewTextBoxEditingControl tb = e.Control as DataGridViewTextBoxEditingControl;
            tb.KeyDown -= dataGridView_KeyDown;
            tb.PreviewKeyDown -= dataGridView_PreviewKeyDown;
            tb.KeyDown += dataGridView_KeyDown;
            tb.PreviewKeyDown += dataGridView_PreviewKeyDown;
        }
    }

    void dataGridView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyData == Keys.Enter)
        {
            <your logic goes here>
        }
    }
3
Asaf