VB.NET KeyDown KeyPress で入力制限を行う

コンピューター

Visual Studio 2019 で検証しています。

入力制限にどちらを使うか(KeyPress、KeyDown)

キーボード入力のイベントには、KeyDown,KeyPress,KeyUpがあり、キーが押された時に KeyDownとKeyPressが発生します。

記事によっては、入力制限を行うコードとしてKeyPressで書かれていたりするのですが、制限対象が文字の時のみ可能です。言い換えると文字が入力されないキーの一部が認識できなかったりHelpキーがスラッシュ(/)と認識されたりします。

サンプルとして

日付を入力するテキストボックスに入力制限をして、数字0から9迄とDelete,Tab,”/”,BackSpace,Enterのみ有効、以外は入力を拒否する。

コードを考えてみました。

KeyPress

Private Sub TextBoxDate_KeyPress(sender As Object, e As Windows.Forms.KeyPressEventArgs)
    Select Case e.KeyChar
        Case ChrW(Windows.Forms.Keys.D0) To ChrW(Windows.Forms.Keys.D9)  ' 数値のみ入力可能
        Case ChrW(Windows.Forms.Keys.Delete) ' 認識されない
        Case ChrW(Windows.Forms.Keys.Tab) ' 認識されない
        Case ChrW(Windows.Forms.Keys.Help) ' なぜか "/" 対応
        Case ChrW(Windows.Forms.Keys.Back) ' 認識される
        Case ChrW(Windows.Forms.Keys.Enter) ' 認識される 
            SelectNextControl(sender, True, True, True, False) ' 次のコントロールへ移動
        Case Else
            e.Handled = True ' 入力を拒否する
        End Select
    End Sub
End Sub

KeyDown

Private Sub TextBoxDate_KeyDown(sender As Object, e As Windows.Forms.KeyEventArgs)
    Select Case e.KeyCode
        Case Windows.Forms.Keys.D0 To Windows.Forms.Keys.D9 ' キーボード側数値
        Case Windows.Forms.Keys.Delete ' 認識される
        Case Windows.Forms.Keys.Tab ' 認識されない
        Case Windows.Forms.Keys.Divide ' テンキー側 /
        Case Windows.Forms.Keys.Back ' 認識される
        Case Windows.Forms.Keys.Enter ' 認識される
            SelectNextControl(sender, True, True, True, False) ' 次のコントロールへ移動
        Case Else
            e.SuppressKeyPress = True ' 入力を拒否する
        End Select
    End Sub
End Sub

結果

文字、数値のみならどちらでも良いのかも知れないですが、対象範囲の広いKeyDownが使いやすいと思います。尚、KeyDownの e.SuppressKeyPress = True が使えるのは.NET Framework 2.0以降らしいですが、今さら以前の物で作る事は無いと思うので気にしなくて良いかと思います。

どちらもTabキーの認識が出来なかったですが、キー動作はするので今回は結果オーライです。抑制する場合、APIでの対応が必要になるみたいです。

一部のキーは環境依存がありえるかも知れないですね。KeyDownでは、同じ数字でもキーボードとテンキーは別コードでした。参考までに、テキストボックスでの日付用、実数用(小数点を含む数値)のコードを掲示しておきます。コピペ対策とか、ShiftやCtrl等を押した状態への配慮はありません。

Private Sub TextBoxDate_KeyDown(sender As Object, e As Windows.Forms.KeyEventArgs)
    Select Case e.KeyCode
        Case Windows.Forms.Keys.D0 To Windows.Forms.Keys.D9 ' キーボード側数値
        Case Windows.Forms.Keys.NumPad0 To Windows.Forms.Keys.NumPad9 ' テンキー側数値
        Case Windows.Forms.Keys.Delete
        ' Case Windows.Forms.Keys.Tab ' 認識できない
        Case Windows.Forms.Keys.Oem2 ' キーボード側 /
        Case Windows.Forms.Keys.Divide ' テンキー側 /
        Case Windows.Forms.Keys.Back
        Case Windows.Forms.Keys.Enter
            SelectNextControl(sender, True, True, True, False) ' 次のコントロールへ移動
        Case Else
            e.SuppressKeyPress = True
        End Select
    End Sub
End Sub
Private Sub TextBoxDecimal_KeyDown(sender As Object, e As Windows.Forms.KeyEventArgs) 
    Select Case e.KeyCode
        Case Windows.Forms.Keys.D0 To Windows.Forms.Keys.D9 ' キーボード側数値
        Case Windows.Forms.Keys.NumPad0 To Windows.Forms.Keys.NumPad9 ' テンキー側数値
        Case Windows.Forms.Keys.Delete
        ' Case Windows.Forms.Keys.Tab ' 認識できない
        Case Windows.Forms.Keys.Oem2 ' キーボード側 /
        Case Windows.Forms.Keys.Divide ' テンキー側 /
        Case Windows.Forms.Keys.Back
        Case Windows.Forms.Keys.OemPeriod ' キーボード側 .
        Case Windows.Forms.Keys.Decimal ' テンキー側 .
        Case Windows.Forms.Keys.Enter
            SelectNextControl(sender, True, True, True, False) ' 次のコントロールへ移動
        Case Else
            e.SuppressKeyPress = True
    End Select
End Sub

コメント

タイトルとURLをコピーしました