忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

テキストボックスの Leave イベントでのエラー処理でフォーカス強制移動する方法について

テキストボックスは各種のデータ入力に使いますが、その入力データのエラーチェックを行うことが普通です。

エラーチェックの方法はいろいろありますが、例えばテキストボックス毎にエラーチェックを行ったり、 登録処理などのタイミングで入力項目を一括でエラーチェックを行い、エラーが在った項目の背景色を変えたりすることなどがあります。

今回は、テキストボックスに個別にエラー処理を行った場合にフォーカス移動させたい場合の方法について説明したいと思います。


■単純にテキストボックスでエラー処理を行う(「Leave」イベント)

先ずフォーム上に1個のテキストボックスと、2個のボタンを張り付けます。 (以下の図参照) 1個のボタンは btnTest の名前でテキストボックスに入力された文字列を表示します。 もう1個のボタンは btnClose の名前で自分のフォームを閉じる様にします。

処理のソースは以下の通りです。テキストボックスのデータのエラー処理を Leave イベントの中で行っています。
数値チェック標準関数の IsNumeric を使って、エラーの場合にはメッセージを表示し、再度フォーカスをテキストボックスに設定しています。 尚、データをより細かくチェックする場合は自分でチェック処理を用意する必要があります。

Public Class frmTextBoxExit

    '「Leave」イベントで個別の入力チェック
    Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave
        Dim str As String = Trim(Me.TextBox1.Text)
        '数値チェック
        If IsNumeric(str) = False Then
            MsgBox("数字のみ入力して下さい!")
            Me.TextBox1.Focus()
        End If
    End Sub

    '「Close」ボタンクリックで自分のウインドウを閉じる
    Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
        Me.Close()
    End Sub

    '「Test」ボタンクリックで入力値を表示する
    Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
        Dim str As String = Trim(Me.TextBox1.Text)
        MsgBox("入力文字列:" & str, , "Test Button")
    End Sub

End Class

テキストボックスに数字「123」を入力し「Test」ボタンをクリックすると以下の表示になります。

さらにテキストボックスに数字ではない文字「qq」を入力すると、「Test」「Close」ボタンのどちらをクリックしても以下の表示になります。

ウインドウを閉じようとして「Close」ボタンをクリックしても、ボタンクリックイベントは発生しません。
これは、「Close」ボタンをクリックで一旦フォーカスがボタンに移動するのですが、 その後発生するテキストボックスの「Leave」イベントが走ってフォーカスが強制的に、テキストボックスに戻されてしまうからです。
これでは、このままの状態ではフォームは閉じなくなります。 (テキストボックスの入力を数字にすれば閉じます。また、ウインドウの右上の「×」をクリックすれば閉じますが)


■「Leave」イベントのエラー処理を強制的に抜け出る方法

「Leave」イベントのエラー処理の中では、フォーム上のアクティブなコントロールは、テキストボックスではなく既に「Close」ボタンの方に移っています。 フォーム上のアクティブなコントロールは ActiveControl プロパティに持っています。 このプロパティはフォーム上のアクティブなコントロールの情報を持っています。(と言うかデータ型がControlです)
このプロパティからコントロールの名前を取得し、「btnClose」であればエラー処理をスキップする様にします。
以下に修正したソースを示します。

Public Class frmTextBoxExit

    '「Leave」イベントで個別の入力チェック
    Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave
        '「アクティブなControl」が「Close」ボタン??
        If Me.ActiveControl.Name = "btnClose" Then
            Exit Sub
        End If

        Dim str As String = Trim(Me.TextBox1.Text)
        '数値チェック
        If IsNumeric(str) = False Then
            MsgBox("数字のみ入力して下さい!")
            Me.TextBox1.Focus()
        End If
    End Sub

    '「Close」ボタンクリックで自分のウインドウを閉じる
    Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
        Me.Close()
    End Sub

    '「Test」ボタンクリックで入力値を表示する
    Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
        Dim str As String = Trim(Me.TextBox1.Text)
        MsgBox("入力文字列:" & str, , "Test Button")
    End Sub

End Class

このソースで実行すると、テキストボックスに数字ではない文字を入力しても、「Close」ボタンのクリックでウインドウが閉じます。

■フォーム上の入力データのエラー処理の考察

上記の様にテキストボックスの個別のエラー処理をスキップするには ActiveControl の名前などを確認すればできることが分かりましたが、 他にボタンなどがあれば、それぞれをチェックする必要があります。
尚、他にテキストボックスが在って、それぞれにエラーチェック処理が在る場合は、 それぞれで ActiveControl でボタンの場合エラー処理をスキップする必要があります。

また、フォームの入力データのチェックには一括で行う方法もあります。
「登録」などのボタンを設置して、フォームの入力データを全て取得して、 登録処理等を行うのが一般的だと思いますので、 そのクリックイベントで各入力データ毎に全てのチェック処理を行います。
各データの中でエラーが在ったコントロールにはその証拠となる様に、 背景色などを変更し見た目でエラーが在ったことを表示した方が良いと思います。 (フォーカスは最初にエラーを発見したコントロールに移動すべきです)

最後に、強制的にフォームを閉じる「Close」ボタン等があれば、 フォーム上のデータを1個でも修正したことがあればその旨を表示し 「修正した個所がありますが、フォームを閉じても宜しいでしょうか?」 などのメッセージで聞くことも必要かと思います。

関連する記事

テキストボックス拡張クラスにプロパティを追加する方法
フォーム上のコントロールで[Enter]キー押下で次のコントロールにフォーカス移動する
フォーム上のコントロールのイベント処理の一括関連付け:[AddHandler,DirectCast]
コントロールの同じイベント処理に複数の関連付けをテスト:[AddHandler,DirectCast]











PR

コメント

コメントを書く