セル内のテキストを編集しているときに、DataGridViewのkeydownイベントが機能しません。
データを保存するためにショートカットAlt + Sを割り当てています。セルが編集モードでない場合は機能しますが、以下のコードが編集モードの場合は機能しません。
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == (Keys.Alt | Keys.S))
{
//save data
}
}
セルが編集モードにあるときはいつでも、そのホストされたコントロールは、それを含む親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#を使用してコントロールのキーストロークをトラップする方法
これを行う別の方法は、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
}
}
私が試した簡単な方法は次のとおりです。
KeyPreview
プロパティをtrue
に設定します。次のようにコーディングします。
Private Sub form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If grd.Focused Then
'Do your work
End If
End Sub
これは、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>
}
}