0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【KPI】英数字以外が入力不可のテキストボックスを作成する。【VB.Net】【C#】

Last updated at Posted at 2020-01-31

以前お仕事で必要になった際に調べて作ったもの。
テキストボックスに、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プロパティは制御不可にしたい。
 ②処理中の描画がされるため、入力不可の文字を入力した瞬間のみ描画されることがあるので、この間は描画したくない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?