ちょっとした、でもとても重宝しているプログラムをご紹介します。
最初は、私が作ったものではなく、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})(]?)$"