【C#】小数点を含むテキストボックスの入力形式制限

テキストボックスの入力形式を制限する方法について、コード量の少なさと汎用性の高さという点で個人的に結論がでたのでまとめます。

 

今回の条件は

  • 整数部と小数部に桁数制限がかかっている
  • マイナスを許容する

だけ!

整数部と小数部の桁数をそれぞれ取得して……という方法も考えましたが、今回は正規表現で入力形式を定義して、一致しているか判定する方法で実現しました。
入力中に制限をかけるのは一筋縄ではいかなそうだったので、Leaveイベントに記載する前提で考えていきます。

 

<前準備>
1.usingで「using System.Text.RegularExpressions;」を指定しておいてください。
2.対象のテキストボックスは必要に応じて入力制限をかけておくとよいと思います。(参考:[C#]TextBoxに数字のみ入力可能にする
 諸事情で少しだけ改造しています。詳細は記事最下部をご参照。

 

例)整数部4桁、小数部2桁(マイナスを許容)

Regex r = new Regex(@"^-?\d{1,4}[.]\d{0,2}$|^-?\d{1,4}$|-?[.]\d{0,2}$");

if (r.IsMatch(textBox1.Text)){
 // 一致
}else{
   // 一致していない
}

ここからさらに、カンマ区切りで表示する処理を追加。

textBox1.Text = (double.Parse(textBox1.Text)).ToString("N2");

フォーマット関連の記述方法は色々あるので好きなものを使用するといいと思います。
(参考:書式を指定して数値を文字列に変換する

フォーマットって数値型からの変換でしか使えないんですかね・・・すごく不格好で何とかしたい;;;

 

入力形式に一致している場合としていない場合の処理を追加し処理を通すと以下のようになります。

 private void textBox1_Leave(object sender, EventArgs e)
        {
            Regex r = new Regex(@"^-?\d{1,4}[.]\d{0,2}$|^-?\d{1,4}$");
            if (r.IsMatch(textBox1.Text))
            {
                label1.Text = "入力OK";
                textBox1.Text = (double.Parse(textBox1.Text)).ToString("N2");

            }
            else
            {
                label1.Text = "整数4桁、小数点2桁で入力してください";
            }
        }

<補足>
0⇒0.00
0.→0.00
.→入力NG
.99⇒入力NG

 

と、ここで問題が。。。。
すでにカンマ区切りのテキストに対して正規表現判定を行おうとすると、当り前のようにNGになります。
例)1234.56⇒OK、1,234.56⇒NG

そのため、テキストボックスの入力値に対してカンマ表記を除いた状態で判定を行う必要があります。
安直に考えたらReplace関数かな……。

string str = textBox1.Text.Replace(",", "");

ということで、最終的に完成したものが下記。

private void textBox1_Leave(object sender, EventArgs e)
        {
            //正規表現
            Regex r = new Regex(@"^-?\d{1,4}[.]\d{0,2}$|^-?\d{1,4}$");

            // カンマが含まれている場合はカンマを取り除く
            string str = textBox1.Text.Replace(",", "");

            if (r.IsMatch(str))
            {
                label1.Text = "入力OK";
                textBox1.Text = (double.Parse(textBox1.Text)).ToString("N2");
            }
            else
            {
                label1.Text = "整数4桁、小数点2桁で入力してください";
            }
        }

 

<おまけ>
入力を数値のみに制限する処理の改造版

 

  1:        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
  2:        {
  3:            // 制御文字は入力可
  4:            if (char.IsControl(e.KeyChar))
  5:            {
  6:                e.Handled = false;
  7:                return;
  8:            }
  9:
 10:            // 数字(0-9)は入力可
 11:            if (char.IsDigit(e.KeyChar))
 12:            {
 13:                e.Handled = false;
 14:                return;
 15:            }
 16:
 17:            // 小数点は1つだけ入力可
 18:            if (e.KeyChar == '.')
 19:            {
 20:                TextBox target = sender as TextBox;
 21:                
 22:                if (target.Text.IndexOf('.') < 0 || (target.SelectionLength != 0 && target.SelectedText.IndexOf('.') != -1))
 23:                {
 24:                    // 複数のピリオド入力はNG
 25:                    e.Handled = false;
 26:                    return;
 27:                }
 28:            }
 29:
 30:            // マイナスは1つだけ入力可
 31:            if (e.KeyChar == '-')
 32:            {
 33:                TextBox target = sender as TextBox;
 34:                if (target.Text.IndexOf('-') < 0 || (target.SelectionLength != 0 && target.SelectedText.IndexOf('-') != -1))
 35:                {
 36:                    // 複数のマイナス入力はNG
 37:                    e.Handled = false;
 38:                    return;
 39:                }
 40:            }
 41:
 42:            // 上記以外は入力不可
 43:            e.Handled = true;
 44:        }

 

マイナスを許容するため、L30~L40を追加しています。
また、参考サイトのコードでは【選択状態から上書きで編集】することに対しては対応していませんでした。
そのため、L22とL34の条件を追加して選択状態かつ選択文字列の中に該当文字が含まれていれば上書き可能としました。

ご参考までに。