忍者ブログ

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

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

テキストボックスの入力を数字のみにする方法

テキストボックスでの入力で、入力される文字を数字のみとしたい場合の方法を示します。

文字の入力を行うとテキストボックスの KeyPress イベントが発生します。 この時に入力された文字をチェックし、数字以外であればその文字を捨てる処理を行います。 尚、 KeyPress イベントでは BackSpaceキー入力の場合も発生しますので、 このキーは有効にする必要があります。

KeyPress イベントで数字チェックを行う

Public Class frmTextBox

    Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
        'キーが [0]~[9] または [BackSpace] 以外の場合イベントをキャンセル
        If Not (("0"c <= e.KeyChar And e.KeyChar <= "9"c) Or e.KeyChar = ControlChars.Back) Then
            'コントロールの既定の処理を省略する場合は true
            e.Handled = True
        End If
    End Sub

    Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
        '[Delete] キーを無効にする場合
        If e.KeyCode = Keys.Delete Then
            e.Handled = True
        End If
    End Sub

End Class

BackSpaceキーなどの制御用のキーは、 KeyPress イベントが発生しません。 そのため、KeyDown イベントでキーコードによりそれぞれの処理を行います。
(上のプログラムでは、Deleteキーを無効にしています。)





KeyPress イベントの処理でほぼ良いのですが、一つ問題があります。 それは、クリップボードからのコピペを行う場合にはKeyPress イベントが発生しないので、 対応を行わないと数字以外でも貼り付けられてしまいます。

テキストボックスのイベントには、クリップボードからの貼り付け時のイベントが在りませんので、 テキストボックスの大元のウインドウ・メッセージ処理の中でそれを行う必要があります。

普通にテキストボックスをフォームに張り付ける場合には、 ウインドウ・メッセージ処理を変更することはできません。 テキストボックスを継承したクラスの中でウインドウ・メッセージ処理を オーバーライドすることで可能になります。

以下にそのテキストボックスを拡張したクラスのソースを示します。

KeyPress イベントで数字チェックを行う

''' 
''' 数字とバックスペース以外の入力を無効にしたTextBox
''' 
Public Class ClsNumTextBox
    Inherits TextBox

    'クリップボード貼付メッセージ
    Const WM_PASTE As Integer = &H302

    ''' 
    ''' WndProc メソッド (override)
    ''' 
    ''' <param name="m">メッセージ</param>
    Protected Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            Case WM_PASTE
                Dim iDataObj As IDataObject = Clipboard.GetDataObject()
                'クリップボードの中身があるか、かつ文字列に変換できるか??
                If (iDataObj IsNot Nothing) And (iDataObj.GetDataPresent(DataFormats.Text) = True) Then
                    '文字列に変換
                    Dim strClip As String = DirectCast(iDataObj.GetData(DataFormats.Text), String)
                    '文字列が数字のみか調べる
                    If Me.ChkClipString(strClip) = False Then
                        'エラーの場合はここで抜ける
                        Return
                    End If
                End If
        End Select

        'メッセージのデフォルト処理を呼出す
        MyBase.WndProc(m)
    End Sub

    ''' 
    ''' コンストラクタ
    ''' 
    Public Sub New()
        MyBase.New()
        'IMEを無効にする
        MyBase.ImeMode = ImeMode.Disable
    End Sub

    ''' 
    ''' KeyPressイベントの処理
    ''' 
    Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs)
        MyBase.OnKeyPress(e)
        'キーが [0]~[9] または [BackSpace] 以外の場合イベントをキャンセル
        If Not (("0"c <= e.KeyChar And e.KeyChar <= "9"c) Or e.KeyChar = ControlChars.Back) Then
            e.Handled = True
        End If
    End Sub

    ''' 
    ''' 文字列のチェック関数
    ''' 
    ''' <param name="strClip">指定文字列</param>
    ''' True:OK, False:NG
    Private Function ChkClipString(ByVal strClip As String) As Boolean
        ChkClipString = False
        If System.Text.RegularExpressions.Regex.IsMatch(strClip, "^[0-9]+$") Then
            Return True
        End If
    End Function

End Class

このソースを別のファイルで作成し、一度コンパイルします。 そうすると、ツールボックスの中に ClsNumTextBox が現れますので、 以下の様にこれをフォーム上に貼り付けます。


結果これを実行しますと、以下の様になります。 クリップボードからの貼り付けで、数字以外は表示されないはずです。

関連する記事

テキストボックスの入力を数字のみにする方法その2(電卓の様な入力)
テキストボックス拡張クラスにプロパティを追加する方法
フォーム上のコントロールで[Enter]キー押下で次のコントロールにフォーカス移動する
フォーム上のコントロールのイベント処理の一括関連付け:[AddHandler,DirectCast]
コントロールの同じイベント処理に複数の関連付けをテスト:[AddHandler,DirectCast]
テキストボックスの Leave イベントでのエラー処理でフォーカス強制移動する方法について











PR

コメント

1. 正規表現置換で簡単にできると思いますが

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged

' 正規表現置換で、数字以外を削除する
' Use a regular-expression replacement to delete all characters other than numbers
TextBox1.Text = System.Text.RegularExpressions.Regex.Replace(TextBox1.Text, "[^0-9]", "")

End Sub

2. 無題

コメント有難うございます。確かにその通りですね。ご指摘ありがとうございました。
コメントを書く