次のコントロールに移動するイベントハンドラ

テキストボックスにデータを入力し、[Enter]キーを押すと次のコントロールに移動する。という仕組みは頻繁に使います。

VB6(Visual Studio 6)では、フォームのデザイン時にこの動作を設定することができましたが、.NETではデザイン時でのこの設定がなくなっています(タブキーでの移動はあります)。

(以下のコードは実際に動作していますが、説明の邪魔になる部分を削除したり手を加えています。従ってこのままでは正しく動作しないことがあります。当ブログのコードは今後とも同様です。
掲載しますコードはベストだと思っているわけではありません。私たちの試行錯誤の結果、ともかく要求機能を満足するものです。
コードがもし読者の皆さんのお役に立つのであれば、コードのダウンロードを別途検討したいと思います。)

プログラムでコントロールの[KeyUp]イベントハンドラーで、[Enter]キーが押されたら、次のコントロールに移動するコードを書きます。

    Public Shared Sub SimpleKeyUp(ByVal sender As Object, _
                  ByVal e As System.Windows.Forms.KeyEventArgs)
        If e.KeyValue = Keys.Enter Then
	 Dim frm As Form = sender.findform
          Dim ctrl As Control = CType(sender, Control)
          Dim blnForwd As Boolean = True

          frm.SelectNextControl(ctrl, blnForwd, True, True, True)
        End If
    End Sub

このプログラムで注目すべきは、[sender](実はコントロール)から、それが配置されている[Form]を補足でき、このフォームで次の[TabIndex]のコントロールにフォーカスを移すことができることです(TabIndexの順番はデザイン時に設定します)。

そしてこのコードは、下のように当該コントロールに[KeyUp]イベントハンドラーとして登録します。

    Public Shared Sub SetSimpleEnterKeyHandler(ByRef ctrl As Control)

        If TypeOf (ctrl) Is TextBoxBase Then
            RemoveHandler CType(ctrl, TextBoxBase).KeyUp, AddressOf SimpleKeyUp
            AddHandler CType(ctrl, TextBoxBase).KeyUp, AddressOf SimpleKeyUp
        ElseIf TypeOf (ctrl) Is ButtonBase Then
            RemoveHandler CType(ctrl, ButtonBase).KeyUp, AddressOf SimpleKeyUp
            AddHandler CType(ctrl, ButtonBase).KeyUp, AddressOf SimpleKeyUp
        ElseIf TypeOf (ctrl) Is ListControl Then
            RemoveHandler CType(ctrl, ListControl).KeyUp, AddressOf SimpleKeyUp
            AddHandler CType(ctrl, ListControl).KeyUp, AddressOf SimpleKeyUp
        End If

        If TypeOf (ctrl) Is CheckBox Then
            RemoveHandler CType(ctrl, CheckBox).KeyUp, AddressOf ChkInstKeyUp
            AddHandler CType(ctrl, CheckBox).KeyUp, AddressOf ChkInstKeyUp
        End If
    End Sub

さらにこのコードは、前回ご紹介しました、[CtrlBindingCollection]クラスの[Cell]サブクラスのコンストラクターでコールされています。

その結果、

Dim CBC As New CtrlBindingCollection
With CBC
  .Bind(TextBox1, “氏名”, “String”, True)
  .Bind(TextBox2, “郵便番号”, “String”, True)
  .Bind(TextBox3, “住所”, “String”, True)
  .Bind(TextBox4, “年齢”, “int”, False)
End With
CBC.テキストクリア
CBC.Display(Datarow)

で[TextBox1]、[TextBox2]、[TextBox3]で[Enter]キーを押すと次のコントロールに移動するイベントハンドラーを割り当て、全コントロールをクリアし、それらのコントロールに[Datarow]の値をデータ型を考慮しながら表示することができます(もちろん別途Displayメソッドと、インスタンスDatarowを準備しておきます)。

ところで、日本語入力しているとき[Enter]キーを押すと直ちに次のコントロールに移動されては困ります。
日本語入力の途中では、通常ひらがなで入力して漢字変換が正しく表示されたところで、確定の[Enter]を押します。漢字入力はまだ続きますので、ここで次に移動したのではいけません。

次回はこれを正しく処理するコードをご紹介します。

error: コピーできません !!