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