.Net(VB、C#)でEnterキーによるコントロール間のフォーカス移動
フォーム上の各コントロールにKeyDownイベント・ハンドラを追加し、そのイベント・ハンドラ内でEnterキーが押されたときの処理として、次の何れかのメソッドを実行させることにより実現できる。
※フォーム全体としてEnterキーを一括処理する方法は後述。
- フォームのProcessTabKeyメソッド
- フォームのSelectNextControlメソッド
ProcessTabKeyメソッドは、呼び出しが単純で簡単だが、オプションとして指定できる機能は移動方向のみとなる。
(Bool値のパラメータにより指定:前方向に移動する(True)/後方向に移動する(False))
SelectNextControlメソッドは移動方向に加え、かなり細かくフォーカス移動処理を制御できる。
例えば、TabStopプロパティがFalseに設定されているコントロールへの移動や、入れ子になったコントロールには移動させないといった制御が可能。
フォーカスの移動方向について、Enterキーのみ押された場合は前方向、Shift+Enterキーが押された場合は後方向とする場合、以下のようにフラグを設定することで対応可能。
1 | Dim forward As Boolean = e.Modifiers <> Keys.Shift |
1 | bool forward = e.Modifiers != Keys.Shift; |
フォーム全体としてEnterキーを一括処理する
コントロールごとにKeyDownイベント・ハンドラを追加して上記の処理を実装すれば、Enterキーによるフォーカス移動が可能となるが、コントロールを追加するたびに同様の処理を実装しなければならない。
フォームのKeyDownイベント・ハンドラでEnterキーの一括処理を行うことで、コントロールの追加で発生する作業が不要となる。
以下は、フォームのKeyDownイベント・ハンドラでEnterキーの一括処理を行うサンプル。
※フォームのKeyPreviewプロパティをTrueに設定しておく
1 2 3 4 5 6 7 8 9 10 11 | Public Class Form1 Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown If e.KeyCode = Keys.Enter Then Dim forward As Boolean = e.Modifiers <> Keys.Shift Me.SelectNextControl(Me.ActiveControl, forward, True, True, True) 'Me.ProcessTabKey(forward)でも可 e.Handled = True End If End Sub End Class |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace CSTest004 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { bool forward = e.Modifiers != Keys.Shift; this.SelectNextControl(this.ActiveControl, forward, true, true, true); //this.ProcessTabKey(forward);でも可 e.Handled = true; } } } } |
Enterキーによるフォーカス移動をスキップする
複数行の入力が可能なTextBoxコントロールにおいて、Enterキーで改行処理が行われるので、Enterキーによるフォーカス移動はさせたくない等の理由でフォーカス移動をキャンセルするには、対象コントロールをそのクラスの種類(型)により判別し、フォーカス移動の処理から除外する。
コントロールの種類(型)を判別するには、TypeOf…Is式(VB.NET)/is演算子(C#)を利用する。
キー処理中のコントロール(=アクティブなコントロール)がTextBoxコントロールであるかを判別し、それがTextBoxコントロールの場合には、そのMultiLineプロパティがTrueかどうか(TextBoxコントロールが複数行対応であるかどうか)を確認する。
MultiLineプロパティがTrueの場合にはEnterキーによるフォーカス移動を行わない。
以下、サンプル。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Public Class Form1 Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown If e.KeyCode = Keys.Enter Then Dim skip As Boolean = False If TypeOf Me.ActiveControl Is TextBox Then If (CType(Me.ActiveControl, TextBox)).Multiline = True Then skip = True End If End If If skip = False Then Dim forward As Boolean = e.Modifiers <> Keys.Shift Me.SelectNextControl(Me.ActiveControl, forward, True, True, True) 'Me.ProcessTabKey(forward)でも可 e.Handled = True End If End If End Sub End Class |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace CSTest004 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { bool skip = false; if (this.ActiveControl is TextBox) { if (((TextBox)this.ActiveControl).Multiline == true) { skip = true; } } if (skip == false) { bool forward = e.Modifiers != Keys.Shift; this.SelectNextControl(this.ActiveControl, forward, true, true, true); //this.ProcessTabKey(forward);でも可 e.Handled = true; } } } } } |