以前お仕事で必要になった際に調べて作ったもの。
テキストボックスに、DBのキー項目となるコードを入力する際、記号などが入力出来てしまうのを弾きたかった。
以下、VB.Netの新しいコード用テキストボックスクラス。
VB.Net
Imports System.Text.RegularExpressions
Public Class CommonClass
''' <summary>
''' 正規表現フォーマット
''' </summary>
Public Enum RegexFormat
LimitLess = 0
Num
AlphaUp
AlphaLow
NumAlphaLowUp
End Enum
''' <summary>
''' コード用テキストボックス
''' </summary>
Public Class CodeTextBox
Inherits TextBox
''' <summary>
''' 入力フォーマット
''' </summary>
Private _Format As RegexFormat = RegexFormat.LimitLess
''' <summary>
''' (保持用)テキスト開始位置
''' </summary>
Private selectionStartCustom As Integer = 0
''' <summary>
''' 入力フォーマット
''' </summary>
Public Property Format() As RegexFormat
Get
Return _Format
End Get
Set(ByVal value As RegexFormat)
_Format = value
End Set
End Property
''' <summary>
''' 正規表現フォーマット文字列取得処理
''' </summary>
''' <param name="regexFormat">正規表現フォーマット</param>
''' <param name="notTarget">true:指定した対象以外を正規表現で取得する</param>
''' <returns>正規表現フォーマット文字列</returns>
Private Function GetRegexFormat(ByVal regexFormat As RegexFormat, ByVal notTarget As Boolean) As String
Dim notFormatWord As String = String.Empty
GetRegexFormat = String.Empty
If notTarget Then
notFormatWord = "^"
End If
Select Case (regexFormat)
Case regexFormat.Num
GetRegexFormat = "[" + notFormatWord + "0-9]"
Exit Select
Case regexFormat.AlphaUp
GetRegexFormat = "[" + notFormatWord + "A-Z]"
Exit Select
Case regexFormat.AlphaLow
GetRegexFormat = "[" + notFormatWord + "a-z]"
Exit Select
Case regexFormat.NumAlphaLowUp
GetRegexFormat = "[" + notFormatWord + "0-9a-zA-Z]"
Exit Select
End Select
End Function
''' <summary>
''' IMEモード(半角のみ入力)
''' </summary>
Protected Overloads Property ImeMode() As ImeMode
Get
Return ImeMode.Disable
End Get
Set(ByVal value As ImeMode)
End Set
End Property
Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
' テキスト開始位置をこの時点で取得
selectionStartCustom = Me.SelectionStart
MyBase.OnKeyPress(e)
End Sub
Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
If Not _Format.Equals(RegexFormat.LimitLess) Then
Dim reg As Regex = New Regex(GetRegexFormat(_Format, True))
Dim result As String = reg.Replace(Me.Text, String.Empty)
If Not result.Equals(Me.Text) Then
Me.Text = result
Me.SelectionStart = selectionStartCustom
End If
End If
MyBase.OnTextChanged(e)
End Sub
End Class
End Class
また、C#版も記述しておく。
C#
classCommonClass{/// <summary>/// 正規表現フォーマット/// </summary>publicenumRegexFormat{LimitLess=0,Num,AlphaUp,AlphaLow,NumAlphaLowUp}/// <summary>/// 正規表現フォーマット文字列取得処理/// </summary>/// <param name="regexFormat">正規表現フォーマット</param>/// <param name="notTarget">true:指定した対象以外を正規表現で取得する</param>/// <returns>正規表現フォーマット文字列</returns>privatestaticstringGetRegexFormat(RegexFormatregexFormat,boolnotTarget){stringformat=string.Empty;stringnotFormatWord=string.Empty;if(notTarget){notFormatWord="^";}switch(regexFormat){caseRegexFormat.Num:format="["+notFormatWord+"0-9]";break;caseRegexFormat.AlphaUp:format="["+notFormatWord+"A-Z]";break;caseRegexFormat.AlphaLow:format="["+notFormatWord+"a-z]";break;caseRegexFormat.NumAlphaLowUp:format="["+notFormatWord+"0-9a-zA-Z]";break;}returnformat;}/// <summary>/// コード用テキストボックス/// </summary>publicclassCodeTextBox:TextBox{/// <summary>/// フォーマット(正規表現の選択)/// </summary>[AmbientValue(RegexFormat.LimitLess)][Localizable(true)]publicRegexFormatFormat{get;set;}/// <summary>/// (保持用)テキスト開始位置/// </summary>privateintselectionStart=0;//[AmbientValue(ImeMode.Disable)]//// プロパティウィンドウ非表示//[Browsable(false)]//// インテリセンス非表示//[EditorBrowsable(EditorBrowsableState.Never)]//public new ImeMode ImeMode { get { return base.ImeMode; } set { base.ImeMode = ImeMode.Disable; } }protectedoverridevoidOnKeyPress(KeyPressEventArgse){// テキスト開始位置をこの時点で取得selectionStart=base.SelectionStart;base.OnKeyPress(e);}protectedoverridevoidOnTextChanged(EventArgse){if(!Format.Equals(RegexFormat.LimitLess)){Regexreg=newRegex(GetRegexFormat(Format,true));stringresult=reg.Replace(this.Text,string.Empty);if(!result.Equals(this.Text)){base.Text=result;base.SelectionStart=selectionStart;}}base.OnTextChanged(e);}}}
・今後の課題
①ImeModeプロパティは制御不可にしたい。
②処理中の描画がされるため、入力不可の文字を入力した瞬間のみ描画されることがあるので、この間は描画したくない。