TextBoxの拡張=TextBoxEx

ちょっとした、でもとても重宝しているプログラムをご紹介します。

最初は、私が作ったものではなく、Balenaの「プログラミング Visual Basic.NET」に載っていたものです。

邦訳は2002年日経BPソフトプレスから出版され、付属のCDにソースが入っていました。そのままここに載せると著作権に抵触するかもしれません。Balenaのブログページ(http://www.dotnet2themax.com/blogs/fbalena/)から”Programming Microsoft Visual Basic .NET 2003″Chapter 18を開くと原書のサンプルページがありコードが載っています。

これは、TextBoxを継承したカスタムコントロールです。これによって、データ型や正規表現のチェックが可能です。
以下にこのプログラムの主要な部分を転載します。当然細かいところは分かりませんが、プログラムの雰囲気は分かると思います。

' 拡張されたTextBoxコントロール
Public Class TextBoxEx
    Inherits System.Windows.Forms.TextBox

    Event InvalidKey(ByVal sender As Object, ByVal e As EventArgs)

    Dim m_IsRequired As Boolean
    <Description("入力が必須である場合には、Trueにします。"), Category("検証")>_
    Property IsRequired() As Boolean
	...... 省略
     End Property

    Dim m_ErrorMessage As String
    <Description("エラー時に表示されるメッセージです。"), Category("検証"。")>_
    Property ErrorMessage() As String
	...
    End Property

  ... 省略

    ' ValidateRegexプロパティ。
     <Description("正規表現を使用して、データを検証します。"), Category("検証")>_
    Property ValidateRegex() As String
        Get
            Return m_ValidateRegex
        End Get
        Set(ByVal Value As String)
            ' これが有効な正規表現であることを検査します。
            Try
                If Value <> "" Then
                    Dim dummy As Boolean = Regex.IsMatch("abcde", Value)
                End If
                m_ValidateRegex = Value
            Catch ex As Exception
                MessageBox.Show(ex.Message, "Invalid Property", _
                        MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End Set
    End Property

    Dim m_ValidateRegex As String

    ' エラーメッセージを表示するオプションのコントロール。
     Dim m_DisplayControl As Control

    <Description("エラーメッセージを表示するコントロールです。"), Category("検証")>_
    Property DisplayControl() As Control
	...... 省略
    End Property

    ' コントロールに設定される値の型です。
    Enum ValidTypes
        Any = 0
        [Byte]
        [Short]
        [Integer]
                     ... 省略
        [DateTime]
    End Enum

    Dim m_ValidType As ValidTypes

    <Description("入力する値のデータ型です。"), Category("検証")>_
    Property ValidType() As ValidTypes
        ......
    End Property

    ' Validateメソッド
     <Description("現在の値が検証テストにパスすると、Trueを返します。">_
    Function Validate(Optional ByVal DisplayMessage As Boolean = True) As Boolean
        Validate = True

        If Me.IsRequired And Me.Text = "" Then
            Validate = False
        End If
        If Validate = True And Me.Text <> "" Then
            Validate = CheckValueType(Me.Text)
        End If
        If Validate = True And Me.ValidateRegex <> "" Then
            Validate = Regex.IsMatch(Me.Text, Me.ValidateRegex)
        End If

        If DisplayMessage And Not (DisplayControl Is Nothing) And Me.ErrorMessage <> "" Then
            If Validate Then
                DisplayControl.Text = ""
            Else
                DisplayControl.Text = Me.ErrorMessage
                DisplayControl.ForeColor = m_ErrroForeColor
            End If
        End If

        If Not Validate And Me.BeepOnError Then Beep()
    End Function

    Function CheckValueType(ByVal o As Object) As Boolean
        Dim res As Object
        Try
            Select Case m_ValidType
                Case ValidTypes.Byte : res = CByte(o)
                Case ValidTypes.Short : res = CShort(o)
                     ... 以下省略
            End Select
              Return True
        Catch
            Return False
        End Try
    End Function

    ' このメソッドは、コントロールがValidatingイベントを発生させるときに実行します。
    Protected Overrides Sub OnValidating(ByVal e As System.ComponentModel.CancelEventArgs)
        If Me.Validate() Then
            MyBase.OnValidating(e)
        Else
            e.Cancel = True
        End If
    End Sub
End Class

このプログラムで一番重要なところは、最後のOnValidatingです。このコントロールにデータを入力し、抜けようとするとこのメソッド(イベント)が起動し、データの整合性をチェックし、誤りがあれば指定のコントロールあるいはErrorProviderにメッセージを表示します。
(このプログラムではエラーメッセをLabel等のコントロールに表示するようになっていますが、私はこの部分をErrorProviderに変える等少し手を入れて使っています。)

このプログラムは、Dllとしてコンパイルしこれを参照設定することで、通常のコンポーネント(TextBox等)と同様に使うことができます。

私は、数字入力および正規表現チェックには必ずこのTextBoxExを使います。

ついでですが、私は郵便番号ではMaskedTextBoxを使いますが、電話番号、携帯電話、Emailの入力にはこのTextBoxExを使います。
郵便番号は、日本中で桁数が同じですが、電話番号では市外、市内局番等桁数が異なりますので、TextBoxExでの正規表現のチェックの方が柔軟性があるからです。
ちなみに、次のような正規表現を使っています(どこかから探してきて自分なりに修正したものです。正誤の保障はありません。Emailはそのまま)。

郵便番号 "^d{3}-d{4}$"
電話番号 "^(d{2,4}-){0,1}d{2,4}-d{4}$"
携帯番号 "^d{2,4}-d{2,4}-d{4}$"
Email "^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$"
error: コピーできません !!