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

Enterキーを押した時に、まるでTabキーを押した時のように、次のコントロールにフォーカスを移す

Enterキーが押された時に、タブオーダーが次のコントロールにフォーカスを移動させるには、現在フォーカスのあるコントロールのKeyDownイベントでEnterキーが押されたかを調べ、Form.ProcessTabKeyメソッドを呼び出します。フォーム上にあるすべてのコントロールのKeyDownイベントでProcessTabKeyメソッドを呼び出すのは面倒ですので、フォームのKeyPreviewプロパティをTrueにして、フォームのKeyDownイベントでProcessTabKeyメソッドを呼び出せばよいでしょう。

VB.NET
コードを隠すコードを選択
'フォームのLoadイベントハンドラ
Private Sub Form1_Load(ByVal sender As Object, _
        ByVal e As EventArgs) Handles MyBase.Load
    'キーイベントをフォームで受け取る
    Me.KeyPreview = True
    'KeyDownイベントハンドラを追加
    AddHandler Me.KeyDown, AddressOf Form1_KeyDown
End Sub

'KeyDownイベントハンドラ
Private Sub Form1_KeyDown(ByVal sender As Object, _
        ByVal e As KeyEventArgs)
    'Enterキーが押されているか確認
    If e.KeyCode = Keys.Enter Then
        'あたかもTabキーが押されたかのようにする
        'Shiftが押されている時は前のコントロールのフォーカスを移動
        Me.ProcessTabKey(Not e.Shift)

        e.Handled = True
    End If
End Sub
C#
コードを隠すコードを選択
//フォームのLoadイベントハンドラ
private void Form1_Load(object sender, EventArgs e)
{
    //キーイベントをフォームで受け取る
    this.KeyPreview = true;
    //KeyDownイベントハンドラを追加
    this.KeyDown += new KeyEventHandler(Form1_KeyDown);
}

//KeyDownイベントハンドラ
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    //Enterキーが押されているか確認
    if (e.KeyCode == Keys.Enter)
    {
        //あたかもTabキーが押されたかのようにする
        //Shiftが押されている時は前のコントロールのフォーカスを移動
        this.ProcessTabKey(!e.Shift);

        e.Handled = true;
    }
}
補足:次のコントロールにフォーカスを移動させる方法は、ProcessTabKeyメソッドを呼び出す以外に、SelectNextControlや、GetNextControlメソッドを使う方法もあります。詳しくは、「タブオーダーで次のコントロールをアクティブにする」をご覧ください。
補足:単一行テキストボックスでEnterキーを押すと、ビープ音が鳴りますが、これを防ぐ方法は、こちらで紹介しています。

KeyDownイベントの代わりに、KeyUpイベントを使うこともできます。両者には一長一短があり、以下のような違いがあります。

  • Buttonなどのコントロールにフォーカスがある時は、Enterキーの押下でKeyDownイベントが発生しません。KeyUpイベントならば発生します。
  • KeyUpイベントでは、IMEで文字を確定する時のEnterキーの押下でもKeyEventArgs.KeyCodeプロパティの値がKeys.Returnになるため、これだけでは通常のEnterの押下と区別ができません。KeyDownイベントでは、IME確定時のEnterキーの押下ではKeyEventArgs.KeyCodeプロパティがKeys.ProcessKeyになるため、通常のEnterと区別できます。
  • メッセージボックスをEnterキーの押下で閉じると、その直後にKeyUpイベントが発生してしまいます。KeyDownイベントは発生しません。

複数行テキストボックスの問題

Enter Instead of Tab」によると、この方法には幾つかの問題があります。

まず、フォームのAcceptButtonプロパティにButtonオブジェクトが設定されている時は、うまくいきません。よって、フォームのAcceptButtonプロパティには何も設定しないようにします。

また、複数行テキストボックスでは、Enterキーで次のコントロールにフォーカスが移動しないようにした方がよいでしょう。「Enter Instead of Tab」では、テキストボックスのMultilineとAcceptsReturnプロパティがTrueの時にフォーカスが移動しないようにするコードが紹介されています。

これに加えて、テキストボックスのMultilineとAcceptsReturnプロパティがTrueの時と、リッチテキストボックスの時は、Ctrlキーを押しながらEnterキーを押すことにより、フォーカスが移動しないようにするコードを以下に示します。

VB.NET
コードを隠すコードを選択
'KeyDownイベントハンドラ
Private Sub Form1_KeyDown(ByVal sender As Object, _
        ByVal e As KeyEventArgs)
    'Enterキーが押されているか確認
    If e.KeyCode = Keys.Enter Then
        '複数行テキストボックスのときは、何もしない
        If TypeOf (Me.ActiveControl) Is TextBox Then
            Dim tb As TextBox = CType(Me.ActiveControl, TextBox)
            If tb.Multiline AndAlso (tb.AcceptsReturn OrElse e.Control) Then
                Return
            End If
        End If
        'リッチテキストボックスのときは、何もしない
        If TypeOf (Me.ActiveControl) Is RichTextBox AndAlso e.Control Then
            Return
        End If
        'あたかもTabキーが押されたかのようにする
        'Shiftが押されている時は前のコントロールのフォーカスを移動
        Me.ProcessTabKey(Not e.Shift)

        e.Handled = True
    End If
End Sub
C#
コードを隠すコードを選択
//KeyDownイベントハンドラ
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    //Enterキーが押されているか確認
    if (e.KeyCode == Keys.Enter)
    {
        //複数行テキストボックスのときは、何もしない
        if (this.ActiveControl is TextBox)
        {
            TextBox tb = (TextBox)this.ActiveControl;
            if (tb.Multiline && (tb.AcceptsReturn || e.Control))
                return;
        }
        //リッチテキストボックスのときは、何もしない
        if (this.ActiveControl is RichTextBox && e.Control)
            return;
        //あたかもTabキーが押されたかのようにする
        //Shiftが押されている時は前のコントロールのフォーカスを移動
        this.ProcessTabKey(!e.Shift);

        e.Handled = true;
    }
}
  • 履歴:
  • 2010/12/1 サンプルで、KeyUpイベントの代わりにKeyDownイベントを使うようにした。頂いたコメントを参考に、KeyUpイベントとKeyDownイベントの違いを追記した。

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

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。