[Enter]キーによるフォーカス移動の実現

ACCESSで作成したフォームでは、[Enter]または[Tab]キーを用いてコントロール間のカーソル移動を行いますが、Visual Studio 2005で作成したフォームでのコントロール間のカーソル移動は[Tab]キーでしか行えません。
作成したフォームで[Enter]キーによるカーソル移動を行いたい場合は、フォームのKeyDownイベントに次の処理を記述します。


Public Class frmUriage
        (略)
   下の2行に見えるステートメントは1行が折り返している
    Private Sub frmUriage_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
        Try
            'フォーム上で[Enter]キーが押された時の処理
           If e.KeyCode = Keys.Enter Then
               '[Enter]キーで移動処理を行わないコントロールの処理
               Dim blnThrough As Boolean = False
                '[Shift]キーが同時に押されていたら、逆順に移動する
               Dim blnForward As Boolean = e.Modifiers <> Keys.Shift
                'テキストボックス(複数行入力)
                If TypeOf Me.ActiveControl Is TextBox _
                    AndAlso CType(Me.ActiveControl, TextBox).Multiline Then blnThrough = True
                  'コンボボックス(リストが開いた状態の場合)
                If TypeOf Me.ActiveControl Is ComboBox _
                    AndAlso CType(Me.ActiveControl, ComboBox).DroppedDown Then blnThrough = True
                If Not blnThrough Then
                    'カーソルを移動する
                    Me.SelectNextControl(Me.ActiveControl, blnForward, True, True, True)                    e.Handled = True
                End If
            End If
        Catch ex As Exception
        End Try
    End Sub
       
(略)
End Class


※この処理を実行するときは、フォームの[KeyPreview]プロパティの値を必ずTrueにして下さい。

しかし、実際に動作確認を行ってみると、コンボボックスコントロール上にカーソルがある状態で[Enter]キーを押した時に無効音が鳴ってしまいます(カーソルの移動は正しく行われています)。

これは、フォームのKeyDownイベントが発生する前に、前処理(コントロール本来が持っているプリプロセス)が発生しているためです。
それを回避するために、先程のコードを以下のように修正してください。


Public Class frmUriage
        (略)
    Private Sub frmUriage_KeyDown( _
        ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown

  End Sub
    Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
        '
フォーム上で[Enter]キーが押された時の前処理(プリプロセス)時の処理
        Dim uKeyCode As Keys = (keyData And Keys.KeyCode)
        Dim uModifiers As Keys = (keyData And Keys.Modifiers)
        Select Case uKeyCode
            Case Keys.Enter
                '[Enter]キーで移動処理を行わないコントロールの処理
                Dim blnThrough As Boolean = False
                '[Shift]
キーが同時に押されていたら、逆順に移動する
                Dim blnForward As Boolean = uModifiers <> Keys.Shift
                '
テキストボックス(複数行入力)
                If TypeOf Me.ActiveControl Is TextBox _
                    AndAlso CType(Me.ActiveControl, TextBox).Multiline Then blnThrough = True
                '
コンボボックス(リストが開いた状態の場合)
                If TypeOf Me.ActiveControl Is ComboBox _
                    AndAlso CType(Me.ActiveControl, ComboBox).DroppedDown Then blnThrough = True

                If Not blnThrough Then
                    'カーソルを移動する
                    Me.SelectNextControl(Me.ActiveControl, blnForward, True, True, True)
                  
Return True

                End If
        End Select
        Return MyBase.ProcessDialogKey(keyData)

    End Function
       
(略)
End Class


前述したプリプロセスの処理とは、フォームのProcessDialogKeyメソッドで行われる処理です。
このため、このメソッドをカスタマイズしてオーバーライド(もともとのコントロールが備えている機能を書き換えるということ)します。
(先のKeyDownイベント内での処理はすべて削除してください)。

※スペース等が抜けている場合があります。


有限会社ビット