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で処理をしています。
※クリップボードの禁止は、継承しないと出来ないようです。