注意:DataGridViewコントロールは、.NET Framework 2.0で新しく追加されました。
MSDNの「DataGridView.ProcessDataGridViewKey Method」に、DataGridViewでEnterキーを押した時に、右矢印キーを押した時と同じ動作を行うようにするコードが紹介されています。ここで紹介されている方法は、DataGridViewクラスの派生クラスを作成し、ProcessDialogKeyとProcessDataGridViewKeyメソッドをオーバーライドして、Enterキーが押された時にProcessRightKeyメソッドを呼び出す方法です。
このMSDNのサンプルを参考して作成した、Enterキーを押すことにより、Tabキーを押した時と同じように、隣のセルにフォーカスが移動するDataGridViewの派生クラスを以下に示します。なお、使用法は、「「○○○クラスの代わりに派生クラスを使用します」の意味は?」を参考にしてください。
ここでは、Tabキーを押した時と同じことをするためにProcessTabKeyメソッドを使用していますが、別の方法もあります。詳しくは、「Enterキーを押した時、まるでTabキーを押したかのように、次のコントロールにフォーカスを移す」をご覧ください。
なおDataGridView.StandardTabプロパティはFalseのままにしておいてください。
Imports System Imports System.Windows.Forms ''' <summary> ''' Enterキーが押された時に、Tabキーが押されたのと同じ動作をする ''' (現在のセルを隣のセルに移動する)DataGridView ''' </summary> Public Class DataGridViewEx Inherits DataGridView <System.Security.Permissions.UIPermission( _ System.Security.Permissions.SecurityAction.Demand, _ Window:=System.Security.Permissions.UIPermissionWindow.AllWindows)> _ Protected Overrides Function ProcessDialogKey( _ ByVal keyData As Keys) As Boolean 'Enterキーが押された時は、Tabキーが押されたようにする If (keyData And Keys.KeyCode) = Keys.Enter Then Return Me.ProcessTabKey(keyData) End If Return MyBase.ProcessDialogKey(keyData) End Function <System.Security.Permissions.SecurityPermission( _ System.Security.Permissions.SecurityAction.Demand, _ Flags:=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)> _ Protected Overrides Function ProcessDataGridViewKey( _ ByVal e As KeyEventArgs) As Boolean 'Enterキーが押された時は、Tabキーが押されたようにする If e.KeyCode = Keys.Enter Then Return Me.ProcessTabKey(e.KeyCode) End If Return MyBase.ProcessDataGridViewKey(e) End Function End Class
using System; using System.Windows.Forms; /// <summary> /// Enterキーが押された時に、Tabキーが押されたのと同じ動作をする /// (現在のセルを隣のセルに移動する)DataGridView /// </summary> public class DataGridViewEx : DataGridView { [System.Security.Permissions.UIPermission( System.Security.Permissions.SecurityAction.Demand, Window = System.Security.Permissions.UIPermissionWindow.AllWindows)] protected override bool ProcessDialogKey(Keys keyData) { //Enterキーが押された時は、Tabキーが押されたようにする if ((keyData & Keys.KeyCode) == Keys.Enter) { return this.ProcessTabKey(keyData); } return base.ProcessDialogKey(keyData); } [System.Security.Permissions.SecurityPermission( System.Security.Permissions.SecurityAction.Demand, Flags = System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] protected override bool ProcessDataGridViewKey(KeyEventArgs e) { //Enterキーが押された時は、Tabキーが押されたようにする if (e.KeyCode == Keys.Enter) { return this.ProcessTabKey(e.KeyCode); } return base.ProcessDataGridViewKey(e); } }
このクラスは、DataGridViewクラスの代わりに使用します。
注意:新しく作成したクラスを、基のコントロールクラスの代わりに使用するという意味が分からないという方は、こちらをご覧ください。
「DataGridView: Make Enter Key Move to Next Column - CodeProject」には、KeyDownとCellEndEditイベントを使用する方法が紹介されています。
DataGridViewは、セルが編集できない場合は、Enterキーを押した時にKeyDownイベントが発生します。しかしセルが編集できる場合は発生しませんので、別の方法を考える必要がありますが、残念ながら良い方法がありません。選択肢の一つがCellEndEditイベントですが、Enterキーが押された時以外(マウスでクリックした時など)でも発生し、Enterキーが押されたどうかの判断ができません。よってこの方法は、Enterキー以外で編集を終了させた場合、おかしな動作になってしまう可能性があります。
この方法によるサンプルを示します。なお、DataGridView.EditModeプロパティをEditOnEnterにすると、正常に機能しなくなります。
'DataGridView1のKeyDownイベントハンドラ Private Sub DataGridView1_KeyDown(sender As Object, _ e As KeyEventArgs) Handles DataGridView1.KeyDown If e.KeyCode = Keys.Enter Then Dim dgv As DataGridView = DirectCast(sender, DataGridView) '最終行最終列の場合は、何もしない(最終行最終列で 'Tabキーを送信すると、次のコントロールにフォーカスが移動) If (dgv.CurrentCellAddress.X = dgv.ColumnCount - 1) AndAlso _ (dgv.CurrentCellAddress.Y = dgv.RowCount - 1) Then Return End If 'Tabキーを送信する SendKeys.Send("{TAB}") 'フォーカスが下に移動しないようにする e.Handled = True End If End Sub 'DataGridView1のCellEndEditイベントハンドラ Private Sub DataGridView1_CellEndEdit(sender As Object, _ e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit Dim dgv As DataGridView = DirectCast(sender, DataGridView) '最終行最終列の場合は、何もしない If (e.ColumnIndex = dgv.ColumnCount - 1) AndAlso _ (e.RowIndex = dgv.RowCount - 1) Then Return End If '最終行以外では、フォーカスを上に移動 '(最終行以外では、編集後、フォーカスが下に移動するため) If e.RowIndex < dgv.RowCount - 1 Then SendKeys.Send("{UP}") End If 'Tabキーを送信する SendKeys.Send("{TAB}") End Sub
//DataGridView1のKeyDownイベントハンドラ private void DataGridView1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { DataGridView dgv = (DataGridView)sender; //最終行最終列の場合は、何もしない(最終行最終列で //Tabキーを送信すると、次のコントロールにフォーカスが移動) if ((dgv.CurrentCellAddress.X == dgv.ColumnCount - 1) && (dgv.CurrentCellAddress.Y == dgv.RowCount - 1)) { return; } //Tabキーを送信する SendKeys.Send("{TAB}"); //フォーカスが下に移動しないようにする e.Handled = true; } } //DataGridView1のCellEndEditイベントハンドラ private void DataGridView1_CellEndEdit( object sender, DataGridViewCellEventArgs e) { DataGridView dgv = (DataGridView)sender; //最終行最終列の場合は、何もしない if ((e.ColumnIndex == dgv.ColumnCount - 1) && (e.RowIndex == dgv.RowCount - 1)) { return; } //最終行以外では、フォーカスを上に移動 //(最終行以外では、編集後、フォーカスが下に移動するため) if (e.RowIndex < dgv.RowCount - 1) { SendKeys.Send("{UP}"); } //Tabキーを送信する SendKeys.Send("{TAB}"); }
補足:「ENTER key as TAB in datagridview issue in vb.net - Stack Overflow」などには、KeyDown、CellEndEdit、SelectionChangedイベントを使用し、CurrentCellプロパティでフォーカスを移動させる方法が紹介されています。しかしこの方法も同じ問題を抱えており、さらにCurrentCellプロパティでフォーカスを移動させる時、例外InvalidOperationExceptionが発生することがあるようです。