以前お仕事で必要になった際に調べて作ったもの。
テキストボックスに、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#
class CommonClass
{
/// <summary>
/// 正規表現フォーマット
/// </summary>
public enum RegexFormat
{
LimitLess = 0,
Num,
AlphaUp,
AlphaLow,
NumAlphaLowUp
}
/// <summary>
/// 正規表現フォーマット文字列取得処理
/// </summary>
/// <param name="regexFormat">正規表現フォーマット</param>
/// <param name="notTarget">true:指定した対象以外を正規表現で取得する</param>
/// <returns>正規表現フォーマット文字列</returns>
private static string GetRegexFormat(RegexFormat regexFormat, bool notTarget)
{
string format = string.Empty;
string notFormatWord = string.Empty;
if (notTarget)
{
notFormatWord = "^";
}
switch (regexFormat)
{
case RegexFormat.Num:
format = "[" + notFormatWord + "0-9]";
break;
case RegexFormat.AlphaUp:
format = "[" + notFormatWord + "A-Z]";
break;
case RegexFormat.AlphaLow:
format = "[" + notFormatWord + "a-z]";
break;
case RegexFormat.NumAlphaLowUp:
format = "[" + notFormatWord + "0-9a-zA-Z]";
break;
}
return format;
}
/// <summary>
/// コード用テキストボックス
/// </summary>
public class CodeTextBox : TextBox
{
/// <summary>
/// フォーマット(正規表現の選択)
/// </summary>
[AmbientValue(RegexFormat.LimitLess)]
[Localizable(true)]
public RegexFormat Format { get; set; }
/// <summary>
/// (保持用)テキスト開始位置
/// </summary>
private int selectionStart = 0;
//[AmbientValue(ImeMode.Disable)]
//// プロパティウィンドウ非表示
//[Browsable(false)]
//// インテリセンス非表示
//[EditorBrowsable(EditorBrowsableState.Never)]
//public new ImeMode ImeMode { get { return base.ImeMode; } set { base.ImeMode = ImeMode.Disable; } }
protected override void OnKeyPress(KeyPressEventArgs e)
{
// テキスト開始位置をこの時点で取得
selectionStart = base.SelectionStart;
base.OnKeyPress(e);
}
protected override void OnTextChanged(EventArgs e)
{
if (!Format.Equals(RegexFormat.LimitLess))
{
Regex reg = new Regex(GetRegexFormat(Format, true));
string result = reg.Replace(this.Text, string.Empty);
if (!result.Equals(this.Text))
{
base.Text = result;
base.SelectionStart = selectionStart;
}
}
base.OnTextChanged(e);
}
}
}
・今後の課題
①ImeModeプロパティは制御不可にしたい。
②処理中の描画がされるため、入力不可の文字を入力した瞬間のみ描画されることがあるので、この間は描画したくない。