Back to Top

プログラムの覚書

Category: コントロール

C# テキストボックス(TextBox)入力制御

Visual Studio等でC#を使用してGUIアプリケーションを作成する場合に使用するTextBoxの説明です。

TextBoxで入力文字(数値・実数・カタカナ・ひらがな・全角文字・半角文字 など)制御をする際の例を記載します。

 

文字列制御関数

入力文字の制御を行いたい文字列の列挙体 InputTextType を作成します。以下の列挙体は例ですので、制御した文字列項目を追加作成して下さい。(列挙体を作成するのは汎用性をもたせるためです)

//入力文字列種別列挙体
public enum InputTextType : short
{
    // 文字(チェックなし)
    String,

    // 整数値
    Digit,

    // 全角カタカナ
    Katakana,
}

特定の文字列に含まれる文字(整数文字・全角カタカナ・TELなど)を判断する関数CheckChar()

特定の文字列を判断する関数CheckString()

を作成します。(文字チェック関数・文字列チェック関数を作成するのは、汎用性を持たせるためです)

//文字のチェックをします。
static public bool CheckChar(char c, InputTextType mode)
{
    bool bc = false;

    switch (mode)
    {
        case InputTextType.Digit:
            bc = IsHalfDigit(c);
            break;
        case InputTextType.Katakana:
            bc = IsDblKatakana(c);
            break;
        default:
            break;
    }

    return (bc);
}

//文字列のチェックをします。
static public bool CheckString(string s, InputTextType mode)
{
    bool bc = false;

    switch (mode)
    {
        case InputTextType.Digit:
            bc = IsHalfDigitStr(s);
            break;
        case InputTextType.Katakana:
            bc = IsDblKatakanaStr(s);
            break;
        default:
            break;
    }

    return (bc);
}

※文字と文字列を判断する関数等の例(IsHalfDigitIsHalfDigitStr関数等は特定文字の判断をご覧ください)

 

半角数値入力制御の例

TextBoxの入力制御は、Enter・Leave・KeyPress・KeyDownイベントで制御します。

EnterとLeaveではおもに、[ENTER]キーではなく、マウスでフォーカス移動された時のために処理しています。

KeyPressでは、特定文字列に含まれる文字以外は、入力出来ないようにしています。

KeyDownでは、[ENTER]キーを押された場合と、特殊キー(ESC・↑・↓)の処理をしています。

private void textBox1_Enter(object sender, EventArgs e)
{
    ((TextBox)sender).ClearUndo();
    ((TextBox)sender).SelectAll();
}

private void textBox1_Leave(object sender, EventArgs e)
{
    ((TextBox)sender).Undo();
}

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == '\b')
    {
        return;
    }

    if (!CheckChar(e.KeyChar, InputTextType.Digit))
    {
        e.Handled = true;
    }
}

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.Up:
            this.ProcessTabKey(false);
            break;
        case Keys.Down:
            this.ProcessTabKey(true);
            break;
        case Keys.Tab:
            e.Handled = false;
            break;
        case Keys.Escape:
            ((TextBox)sender).Undo();
            ((TextBox)sender).ClearUndo();
            break;
        case Keys.Enter:
            bool bc = CheckString(((TextBox)sender).Text, InputTextType.Digit);
            if (bc)
            {
                ((TextBox)sender).ClearUndo();
                this.ProcessTabKey(true);
                e.Handled = false;
            }
            break;
        default:
            break;
    }
}

CheckChar()・とCheckString()のInputTextType列挙体の値を変えることにより入力文字列を制御できます。

以上TextBoxでの入力制御の方法の例です。

※ちなみに以上の制御では、クリップボードによるコピーは避けられません。

 

C# TextBox継承以外での入力制限

TextBoxの入力制御をする場合、継承しないで制御すると何度も同じ文を書くことになり効率が悪くなりますが、都合所継承しないで書かなければならない場合の書き方です。

TextBoxを継承しないで入力制御する方法を掲載します。

TextBox入力制御クラス

using System;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace TextBoxSample
{
    class TextBoxUpper
    {
        public delegate void Enter_Delegate(object sender); 

        public enum InputTextType : short
        {
            // 文字(チェックなし)
            String,

            // 整数値
            Digit,

            // 実数値
            Realnum,

            // 日付(0000/00/00)
            Date,
            
            // 全角カタカナ
            Katakana,
        }

        private Regex _CharHalfDigit = new Regex(@"^[0-9-]+$");
        private Regex _CharHalfRealnum = new Regex(@"^[0-9.-]+$");
        private Regex _CharHalfDate = new Regex(@"^[0-9/]+$");

        private Regex _StrHalfDate = new Regex(@"\A([0-9]{2,4})/([0-9]{2})/([0-9]{2})\z");
        private Regex _DblKatakana = new Regex("^[ァ-ヴ!ー]+$");

        //文字列マッチ
        static private bool _IsMatchString(Regex regex, string s)
        {
            if (!regex.IsMatch(s))
            {
                return false;
            }
            return true;
        }

        //キャラクタマッチ
        static private bool _IsMatchChar(Regex regex, char c)
        {
            if (!regex.IsMatch(c.ToString()))
            {
                return false;
            }
            return true;
        }

        TextBox _TextBox;

        //ENTERキー呼び出し
        public Enter_Delegate EnterFunc = null;
 
        public TextBoxUpper(TextBox sender)
        {
            _TextBox = sender;

            _TextBox.Enter += new EventHandler(this.Enter);
            _TextBox.Leave += new EventHandler(this.Leave);
            _TextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.KeyPress);
            _TextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.KeyDown);
            _TextBox.Click += new EventHandler(this.Click);

        }

        //入力タイプ
        private InputTextType _InputType = InputTextType.String;
        public InputTextType InputType
        {
            get { return _InputType; }
            set { _InputType = value; }
        }

        //フォーマット
        private string _FormatString = ""; 
        public string FormatString
        {
            set { _FormatString = value.Trim(); }
            get { return _FormatString; }
        }

        //空入力許可
        private bool _EmptyInput = false;
        public bool EmptyInput
        {
            set { _EmptyInput = value; }
            get { return _EmptyInput; }
        }

        //データ設定
        public string Data
        {
            set
            {
                if (!_DataFormat(value))
                {
                    _TextBox.Text = value;
                }
            }
        }

        //データのチェックと表示
        private bool _DataFormat(string s)
        {
            bool rc = true;

            if (InputType == InputTextType.Digit)
            {
                long lval;
                if (long.TryParse(s, System.Globalization.NumberStyles.Number,
                                     System.Globalization.CultureInfo.InvariantCulture, out lval))
                {
                    if (_FormatString != "")
                    {
                        _TextBox.Text = lval.ToString(_FormatString);
                    }
                }
                else
                {
                    rc = false;
                }
            }
            else if (InputType == InputTextType.Realnum)
            {
                double dval;
                if (double.TryParse(s, System.Globalization.NumberStyles.Number,
                                       System.Globalization.CultureInfo.InvariantCulture, out dval))
                {
                    if (_FormatString != "")
                    {
                        _TextBox.Text = dval.ToString(_FormatString);
                    }
                }
                else
                {
                    rc = false;
                }
            }
            else if (InputType == InputTextType.Date)
            {
                int ival;
                if (int.TryParse(s, System.Globalization.NumberStyles.Number,
                                    System.Globalization.CultureInfo.InvariantCulture, out ival))
                {
                    s = ival.ToString("####/00/00");
                }

                DateTime dt;
                if (DateTime.TryParse(s, new System.Globalization.CultureInfo("ja-JP"),
                                             System.Globalization.DateTimeStyles.AssumeLocal, out dt))
                {
                    _TextBox.Text = dt.ToString("yyyy/MM/dd");
                }
                else
                {
                    rc = false;
                }
            }
            else if (InputType == InputTextType.Katakana)
            {
                if (!_IsMatchString(_DblKatakana, s))
                {
                    rc = false;
                }
            }
            else
            {
            }

            return rc;
        }

        /// <summary>
        /// Enter イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Enter(object sender, EventArgs e)
        {
            ((TextBox)sender).ClearUndo();

            if (InputType == InputTextType.Digit || InputType == InputTextType.Realnum || InputType == InputTextType.Date)
            {
                ((TextBox)sender).SelectAll();
            }
        }

        /// <summary>
        /// Leave イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void Leave(object sender, EventArgs e)
        {
            ((TextBox)sender).Undo();
        }

        /// <summary>
        /// KeyPress イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Back)
            {
                return;
            }

            switch (InputType)
            {
                case InputTextType.Digit:
                    if (!_IsMatchChar(_CharHalfDigit, e.KeyChar))
                    {
                        e.Handled = true;
                    }
                    break;
                case InputTextType.Realnum:
                    if (!_IsMatchChar(_CharHalfRealnum, e.KeyChar))
                    {
                        e.Handled = true;
                    }
                    break;
                case InputTextType.Date:
                    if (!_IsMatchChar(_CharHalfDate, e.KeyChar))
                    {
                        e.Handled = true;
                    }
                    break;
                case InputTextType.Katakana:
                    if (!_IsMatchChar(_DblKatakana, e.KeyChar))
                    {
                        e.Handled = true;
                    }
                    break;
                case InputTextType.String:
                    break;
            }
        }

        /// <summary>
        /// KeyDown イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:
                    ((TextBox)sender).TopLevelControl.SelectNextControl(((TextBox)sender), false, true, true, true);
                    break;
                case Keys.Down:
                    ((TextBox)sender).TopLevelControl.SelectNextControl(((TextBox)sender), true, true, true, true);
                    break;
                case Keys.Tab:
                    e.Handled = false;
                    break;
                case Keys.Escape:
                    ((TextBox)sender).Undo();
                    ((TextBox)sender).ClearUndo();
                    break;
                case Keys.Enter:
                    bool rc = true;
                    
                    string s = ((TextBox)sender).Text;

                    if (_EmptyInput && s == "")
                    {
                    }
                    else
                    {
                        rc = _DataFormat(s);
                    }

                    if (rc)
                    {
                        ((TextBox)sender).ClearUndo();

                        if (EnterFunc != null)
                        {
                            EnterFunc(sender);
                        }

                        ((TextBox)sender).TopLevelControl.SelectNextControl(((TextBox)sender), true, true, true, true);
                    }
                    else
                    {
                        System.Media.SystemSounds.Beep.Play();
                    }

                    e.Handled = false;
                    break;
            }
        }

        /// <summary>
        /// Click イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void Click(object sender, EventArgs e)
        {
            if (InputType == InputTextType.Digit || InputType == InputTextType.Realnum || InputType == InputTextType.Date)
            {
                ((TextBox)sender).SelectAll();
            }
        }
    }
}

 

使用方法

using System;
using System.Windows.Forms;

namespace TextBoxSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        TextBoxUpper _TextBoxUpper1;
        TextBoxUpper _TextBoxUpper2;
        TextBoxUpper _TextBoxUpper3;
        TextBoxUpper _TextBoxUpper4;

        private void Form1_Load(object sender, EventArgs e)
        {
            _TextBoxUpper1 = new TextBoxUpper(textBox1);
            _TextBoxUpper1.InputType = TextBoxUpper.InputTextType.Date;

            _TextBoxUpper2 = new TextBoxUpper(textBox2);
            _TextBoxUpper2.InputType = TextBoxUpper.InputTextType.Katakana;
            _TextBoxUpper2.EmptyInput = true;

            _TextBoxUpper3 = new TextBoxUpper(textBox3);
            _TextBoxUpper3.FormatString = "###,###,###";
            _TextBoxUpper3.InputType = TextBoxUpper.InputTextType.Digit;
            _TextBoxUpper3.EnterFunc = textBox_EnterFunc;
            textBox3.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox3Last_KeyDown);
            _TextBoxUpper3.Data = "1000";

            _TextBoxUpper4 = new TextBoxUpper(textBox4);
            _TextBoxUpper4.FormatString = "#.0";
            _TextBoxUpper4.InputType = TextBoxUpper.InputTextType.Realnum;
            _TextBoxUpper4.Data = "10";
        }

        private void textBox_EnterFunc(object sender)
        {
            long lv = long.Parse(textBox3.Text, System.Globalization.NumberStyles.Number,
                                                System.Globalization.CultureInfo.InvariantCulture);

            double dv = double.Parse(textBox4.Text, System.Globalization.NumberStyles.Number,
                                                    System.Globalization.CultureInfo.InvariantCulture);
            label1.Text = (lv * dv).ToString();
        }

        private void textBox3_KeyDown(object sender, KeyEventArgs e)
        {
        }

        private void textBox3Last_KeyDown(object sender, KeyEventArgs e)
        {
        }
    }
}

[ENTER]キーにて処理をする場合、KeyDownの順番に注意が必要

1.textBox3_KeyDown

2.TextBoxUpper内のKeyDown

3.textBox3Last_KeyDown

の順番になります。のでtextBox_EnterFuncで処理をしています。

※クリップボードの禁止は、継承しないと出来ないようです。