数値のみを受け入れるテキストボックスを作成するにはどうすればよいですか?


583

整数値のみを受け入れたいテキストボックスコントロールを備えたWindowsフォームアプリがあります。以前は、KeyPressイベントをオーバーロードして、仕様に適合しない文字を削除することで、この種の検証を行っていました。私はMaskedTextBoxコントロールを見てきましたが、おそらく正規表現で動作する、または他のコントロールの値に依存する、より一般的な解決策が欲しいです。

理想的には、これは数字以外の文字を押しても結果が生成されないか、無効な文字に関するフィードバックがすぐにユーザーに提供されるように動作します。


11
数字や数字?大きな違い:整数であっても負になる可能性がある
Joel Coehoorn、2009年

8
この質問は、有理数のセット全体を含む数を対象としています。
Mykroft 2009年

回答:


797

2つのオプション:

  1. NumericUpDown代わりに使用してください。NumericUpDownがフィルタリングを行います。もちろん、キーボードの上矢印と下矢印を押して現在の値を増減させることもできます。

  2. 適切なキーボードイベントを処理して、数値入力以外のことを防止します。標準のTextBoxでこの2つのイベントハンドラーを使用して成功しました。

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) &&
            (e.KeyChar != '.'))
        {
                e.Handled = true;
        }
    
        // only allow one decimal point
        if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
        {
            e.Handled = true;
        }
    }

TextBoxが小数位を許可しない場合は、このチェック'.'(およびその後の複数のチェック)を削除でき'.'ます。'-'TextBoxが負の値を許可するかどうかのチェックを追加することもできます。

ユーザーの桁数を制限する場合は、次を使用します。 textBox1.MaxLength = 2; // this will allow the user to enter only 2 digits


5
NumericUpDownの唯一の欠点は、許可された最大値または最小値以外の値を入力したときにフィードバックが提供されないことです。入力した内容が変更されるだけです。TextBoxは少なくとも無効な値を許可できるため、ユーザーがフォームを送信するときにユーザーに警告できます。
マットハミルトン

7
それは本当です-ユーザーは常にいくつかの非数値文字を貼り付けることができました。ただし、ある時点でInt32.TryParseなどを実行したいので、フォームの検証でこれがキャッチされることを期待します。
マットハミルトン

52
'。'のチェックを置き換えることにより、これをグローバル化するための追加の作業が必要になります。CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparatorをチェックします。
ジェフイエーツ

6
@ HamishGrubijan、IsControlはControlキーとは関係ありません。charが制御文字かどうかを返します。制御文字を許可することで、バックスペース、削除、矢印キーなどを壊すことがなくなります
Thomas Levesque '31 / 10/31

13
ところで、これはまだ不正なctrl + v入力を受け入れます。公式のNumericUpDownコントロールにも存在するバグ。
Nyerguds、2015

149

そして、1行で作業を行う方が常に楽しいからです...

 private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
    }

注:これは、ユーザーがこのテキストボックスにコピー/貼り付けすることを妨げるものではありません。これは、データをサニタイズするための確実な方法ではありません。


これは整数でのみ機能するため、一般的なソリューションではありません。私は最近そのようなものを実装する必要があり、結果の文字列を数値に解析して、解析が成功した場合にのみ入力を許可することになりました
grzegorz_p

1
複数のメソッドKeyPressが同じテキストボックスからのイベントを処理する場合、これは機能しない可能性があります。1つのイベントe.Handledをtrueに設定し、次に別のイベントをfalseに戻すことができます。一般的には、使用する方が良いif (...) e.Handled = true;
ナサニエルジョーンズ

2
ShortcutsEnabledプロパティを無効にして、キーボードまたはメニューによるコピーの貼り付けを防ぐことができます
Ahmad

3
はは!はい!ワンライナー!
ジェイミーL.

3
ええ TextChanged正規表現でそれを乗り越えるには、コピー&ペーストを修正することができますイベント;)
Nyerguds

51

コンテキストと使用したタグから、.NET C#アプリを作成していると想定しています。この場合、テキスト変更イベントをサブスクライブして、各キーストロークを検証できます。

private void textBox1_TextChanged(object sender, EventArgs e)
{
    if (System.Text.RegularExpressions.Regex.IsMatch(textBox1.Text, "[^0-9]"))
    {
        MessageBox.Show("Please enter only numbers.");
        textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1);
    }
}

22
数字の途中で入力すると、非常に奇妙な効果が得られませんか?
Colin Pickard

5
そしてまた、それはする必要があります:textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1);
Pieniadz

3
最初の文字自体が数字でない場合...その場合に1を減算しないとエラーがスローされます...
manu_dilip_shah

6
また、KeyPressの代わりにTextChangedを使用すると、コードがRemoveメソッドの後に2番目のTextChangedイベントにジャンプするという点で、少し再帰が発生します。
WEFX 2013年

2
IsMatch関数の入力パラメーターとパターンパラメーターを切り替えました。最初に入力、次にパターンを入力する必要があります。msdn.microsoft.com/en-us/library/sdx2bds0(v=vs.110).aspx
Mibou

36

これは、標準のTextBoxから派生したシンプルなスタンドアロンのWinformsカスタムコントロールで、System.Int32入力のみを許可します(System.Int64などの他のタイプに簡単に適合させることができます)。コピー/貼り付け操作と負の数をサポートします:

public class Int32TextBox : TextBox
{
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        base.OnKeyPress(e);

        NumberFormatInfo fi = CultureInfo.CurrentCulture.NumberFormat;

        string c = e.KeyChar.ToString();
        if (char.IsDigit(c, 0))
            return;

        if ((SelectionStart == 0) && (c.Equals(fi.NegativeSign)))
            return;

        // copy/paste
        if ((((int)e.KeyChar == 22) || ((int)e.KeyChar == 3))
            && ((ModifierKeys & Keys.Control) == Keys.Control))
            return;

        if (e.KeyChar == '\b')
            return;

        e.Handled = true;
    }

    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        const int WM_PASTE = 0x0302;
        if (m.Msg == WM_PASTE)
        {
            string text = Clipboard.GetText();
            if (string.IsNullOrEmpty(text))
                return;

            if ((text.IndexOf('+') >= 0) && (SelectionStart != 0))
                return;

            int i;
            if (!int.TryParse(text, out i)) // change this for other integer types
                return;

            if ((i < 0) && (SelectionStart != 0))
                return;
        }
        base.WndProc(ref m);
    }

2017年の更新:最初の回答にはいくつか問題があります。

  • 特定の型の整数よりも長いものを入力できます(たとえば、2147483648はInt32.MaxValueより大きい)。
  • より一般的には、実際の検証はありません 結果の入力され。
  • これはint32のみを処理するため、タイプごとに特定のTextBox派生コントロールを作成する必要があります(Int64など)。

だから私はより一般的な別のバージョンを思いついた、それはまだコピー/貼り付け、+と-記号などをサポートしている。

public class ValidatingTextBox : TextBox
{
    private string _validText;
    private int _selectionStart;
    private int _selectionEnd;
    private bool _dontProcessMessages;

    public event EventHandler<TextValidatingEventArgs> TextValidating;

    protected virtual void OnTextValidating(object sender, TextValidatingEventArgs e) => TextValidating?.Invoke(sender, e);

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (_dontProcessMessages)
            return;

        const int WM_KEYDOWN = 0x100;
        const int WM_ENTERIDLE = 0x121;
        const int VK_DELETE = 0x2e;

        bool delete = m.Msg == WM_KEYDOWN && (int)m.WParam == VK_DELETE;
        if ((m.Msg == WM_KEYDOWN && !delete) || m.Msg == WM_ENTERIDLE)
        {
            DontProcessMessage(() =>
            {
                _validText = Text;
                _selectionStart = SelectionStart;
                _selectionEnd = SelectionLength;
            });
        }

        const int WM_CHAR = 0x102;
        const int WM_PASTE = 0x302;
        if (m.Msg == WM_CHAR || m.Msg == WM_PASTE || delete)
        {
            string newText = null;
            DontProcessMessage(() =>
            {
                newText = Text;
            });

            var e = new TextValidatingEventArgs(newText);
            OnTextValidating(this, e);
            if (e.Cancel)
            {
                DontProcessMessage(() =>
                {
                    Text = _validText;
                    SelectionStart = _selectionStart;
                    SelectionLength = _selectionEnd;
                });
            }
        }
    }

    private void DontProcessMessage(Action action)
    {
        _dontProcessMessages = true;
        try
        {
            action();
        }
        finally
        {
            _dontProcessMessages = false;
        }
    }
}

public class TextValidatingEventArgs : CancelEventArgs
{
    public TextValidatingEventArgs(string newText) => NewText = newText;
    public string NewText { get; }
}

Int32の場合、次のように、そこから派生させることができます。

public class Int32TextBox : ValidatingTextBox
{
    protected override void OnTextValidating(object sender, TextValidatingEventArgs e)
    {
        e.Cancel = !int.TryParse(e.NewText, out int i);
    }
}

または派生なしの場合、次のような新しいTextValidatingイベントを使用します。

var vtb = new ValidatingTextBox();
...
vtb.TextValidating += (sender, e) => e.Cancel = !int.TryParse(e.NewText, out int i);

しかし、良いのは、任意の文字列と任意の検証ルーチンで機能することです。


これは素晴らしく、素晴らしく、シンプルで、簡単に使用でき、異常な入力試行を処理します。ありがとう!
WiredEarp 2015

1
2017年版の注意事項、そこに一つの値例えば1であり、あなたが持っていたならば、我々は1が残っている120とヒットバックスペース三回言うながら、それは無視されますバックスペースを打つ
カレン・ペイン

1
あなたのValidatingTextboxは、私がしばらく見てきた中で最高の実装です。シンプルで効果的。ありがとう!
サミュエル

19

これは、検証/検証イベントが設計されたまさにそのためです。

これは、トピックに関するMSDNの記事です。http//msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx

TL; DRバージョン:Validatingイベントの.Textプロパティを確認して設定します e.Cancel=True、データが無効な場合にします。

e.Cancel = Trueを設定すると、ユーザーはフィールドを離れることはできませんが、何かが間違っているというフィードバックを提供する必要があります。問題を示すために、ボックスの背景色を明るい赤に変更します。SystemColors.WindowValidatingが適切な値で呼び出された場合は、必ずに戻してください。


1
非常にAPI慣用的なアプローチについて言及した場合は+1。私はWindowsフォームに比較的慣れていないので、機能とMSDNドキュメントのジャングルです。したがって、への特定のドキュメントポインターにも感謝しますValidating<nitpick>OPは、無効化する文字をすぐに禁止/示すことが理想的であるValidatingと述べていますが、有効になる前にフォーカスを別のフォーム/コントロールに移動する必要があるようです。</nitpick>それでも、これは優れたアプローチであり、より一般的なケースでは常に検討する価値があります。
ウィリアム

13

MaskedTextBoxを試してください。単純なマスク形式を使用するため、入力を数値や日付などに制限できます。


2
特にMaskedTextBoxを使用したくありません。彼らが許可するフォーマットは非常に制限的です。彼らはこのケースで機能しますが、もっと一般的なことをしたいと思います。
Mykroft 2009年

12

TextChangedイベントを利用できます

private void textBox_BiggerThan_TextChanged(object sender, EventArgs e)
{
    long a;
    if (! long.TryParse(textBox_BiggerThan.Text, out a))
    {
        // If not int clear textbox text or Undo() last operation
        textBox_LessThan.Clear();
    }
}

使用した場合は問題なく動作するようですUndo()が、結果はになりStackOverflowExceptionます。
ドリューシャピン2015年

TextChangedプロパティは、undo()を実行したいルーチンの一部のようです。ウィンドウ全体に変数があり、を使用していますpublic int txtBoxValue。tryParseが機能しない場合は、txtBoxのテキストを元に戻しますtxtBox.Text = txtBoxValue.ToString();
L.

8

これは便利かもしれません。これにより、適切な小数点や先行するプラス記号またはマイナス記号を含む「実際の」数値が許可されます。関連するKeyPressイベント内から呼び出します。

       private bool IsOKForDecimalTextBox(char theCharacter, TextBox theTextBox)
    {
        // Only allow control characters, digits, plus and minus signs.
        // Only allow ONE plus sign.
        // Only allow ONE minus sign.
        // Only allow the plus or minus sign as the FIRST character.
        // Only allow ONE decimal point.
        // Do NOT allow decimal point or digits BEFORE any plus or minus sign.

        if (
            !char.IsControl(theCharacter)
            && !char.IsDigit(theCharacter)
            && (theCharacter != '.')
            && (theCharacter != '-')
            && (theCharacter != '+')
        )
        {
            // Then it is NOT a character we want allowed in the text box.
            return false;
        }



        // Only allow one decimal point.
        if (theCharacter == '.'
            && theTextBox.Text.IndexOf('.') > -1)
        {
            // Then there is already a decimal point in the text box.
            return false;
        }

        // Only allow one minus sign.
        if (theCharacter == '-'
            && theTextBox.Text.IndexOf('-') > -1)
        {
            // Then there is already a minus sign in the text box.
            return false;
        }

        // Only allow one plus sign.
        if (theCharacter == '+'
            && theTextBox.Text.IndexOf('+') > -1)
        {
            // Then there is already a plus sign in the text box.
            return false;
        }

        // Only allow one plus sign OR minus sign, but not both.
        if (
            (
                (theCharacter == '-')
                || (theCharacter == '+')
            )
            && 
            (
                (theTextBox.Text.IndexOf('-') > -1)
                ||
                (theTextBox.Text.IndexOf('+') > -1)
            )
            )
        {
            // Then the user is trying to enter a plus or minus sign and
            // there is ALREADY a plus or minus sign in the text box.
            return false;
        }

        // Only allow a minus or plus sign at the first character position.
        if (
            (
                (theCharacter == '-')
                || (theCharacter == '+')
            )
            && theTextBox.SelectionStart != 0
            )
        {
            // Then the user is trying to enter a minus or plus sign at some position 
            // OTHER than the first character position in the text box.
            return false;
        }

        // Only allow digits and decimal point AFTER any existing plus or minus sign
        if  (
                (
                    // Is digit or decimal point
                    char.IsDigit(theCharacter)
                    ||
                    (theCharacter == '.')
                )
                &&
                (
                    // A plus or minus sign EXISTS
                    (theTextBox.Text.IndexOf('-') > -1)
                    ||
                    (theTextBox.Text.IndexOf('+') > -1)
                )
                &&
                    // Attempting to put the character at the beginning of the field.
                    theTextBox.SelectionStart == 0
            )
        {
            // Then the user is trying to enter a digit or decimal point in front of a minus or plus sign.
            return false;
        }

        // Otherwise the character is perfectly fine for a decimal value and the character
        // may indeed be placed at the current insertion position.
        return true;
    }

6

WinFormsで不足しているものを完成させるために、コンポーネントのコレクションに取り組んでいます。 Advanced Forms

特に、これはRegex TextBoxのクラスです

/// <summary>Represents a Windows text box control that only allows input that matches a regular expression.</summary>
public class RegexTextBox : TextBox
{
    [NonSerialized]
    string lastText;

    /// <summary>A regular expression governing the input allowed in this text field.</summary>
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public virtual Regex Regex { get; set; }

    /// <summary>A regular expression governing the input allowed in this text field.</summary>
    [DefaultValue(null)]
    [Category("Behavior")]
    [Description("Sets the regular expression governing the input allowed for this control.")]
    public virtual string RegexString {
        get {
            return Regex == null ? string.Empty : Regex.ToString();
        }
        set {
            if (string.IsNullOrEmpty(value))
                Regex = null;
            else
                Regex = new Regex(value);
        }
    }

    protected override void OnTextChanged(EventArgs e) {
        if (Regex != null && !Regex.IsMatch(Text)) {
            int pos = SelectionStart - Text.Length + (lastText ?? string.Empty).Length;
            Text = lastText;
            SelectionStart = Math.Max(0, pos);
        }

        lastText = Text;

        base.OnTextChanged(e);
    }
}

次のようなものを追加するだけでmyNumbericTextBox.RegexString = "^(\\d+|)$";十分です。


5

NumericUpDownコントロールを使用して、醜い上下ボタンの表示をに設定しますfalse

numericUpDown1.Controls[0].Visible = false;

NumericUpDown 実際には、「スピンボックス」(上下ボタン)、テキストボックス、およびそれをすべて検証および変更するコードを含むコントロールのコレクションです。

マーキング:

YourNumericUpDown.Controls[0].visible = false 

基になるコードをアクティブに保ちながらボタンを非表示にします。

明白な解決策ではありませんが、それはシンプルで効果的です。.Controls[1]代わりにテキストボックス部分を非表示にする場合は、


受け入れられた回答には、上下ボタンを削除する方法に関する情報は含まれていませんでした。有効または無効にするための人間が読めるインターフェースがないため、削除方法は明らかではありません。NumericUpDownは実際には、テキストボックスと「スピンボックス」(上向きのボタン)、および入力検証を処理するいくつかのコードを含むコントロールのコレクションです。
user2163234 2017年

4

私はCodePlexでこれのために何かを作りました

TextChangedイベントをインターセプトすることで機能します。結果が適切な数値である場合は、保存されます。何か問題がある場合は、最後の適切な値が復元されます。ソースは大きすぎてここで公開できませんが、このロジックのコアを処理するクラスへのリンクがあります。


4

単にこのコードをtextboxで使用してください:

private void textBox1_TextChanged(object sender, EventArgs e)
{

    double parsedValue;

    if (!double.TryParse(textBox1.Text, out parsedValue))
    {
        textBox1.Text = "";
    }
}

4

textboxの定義があるウェブページで、onkeypress数字のみを受け入れるイベントを追加できます。メッセージは表示されませんが、誤った入力を防ぐことができます。それは私のために働いた、ユーザーは数字以外は何も入力できなかった。

<asp:TextBox runat="server" ID="txtFrom"
     onkeypress="if(isNaN(String.fromCharCode(event.keyCode))) return false;">


2

KeyDownイベントで処理します。

void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            char c = Convert.ToChar(e.PlatformKeyCode);
            if (!char.IsDigit(c))
            {
                e.Handled = true;
            }
        }

2
どのような「バックスペース」、「削除」、「矢印キー左」、「矢印キー右」、コピー&ペーストなどのキーについて、数字はテンキー(それらが数字として取引されている!の)によって入力された
user799821

ただ、このようないくつかのより多くのテストを追加します。if(!char.IsDigit(C)&& C =(char型)Keys.Back)
dnennis

2
private void txt3_KeyPress(object sender, KeyPressEventArgs e)
{
    for (int h = 58; h <= 127; h++)
    {
        if (e.KeyChar == h)             //58 to 127 is alphabets tat will be         blocked
        {
            e.Handled = true;
        }
    }
    for(int k=32;k<=47;k++)
    {
        if (e.KeyChar == k)              //32 to 47 are special characters tat will 
        {                                  be blocked
            e.Handled = true;
        }
    }
}

これはとても簡単です


2

を見てみましょう WinForm入力処理を

テキストボックスにProcessCmdKeyイベントとOnKeyPressイベントを使用するソリューションを投稿しました。コメントは、Regexを使用してキーを確認し、適切にブロック/許可する方法を示しています。


2

こんにちは、テキストボックスのtextchangedイベントでこのようなことを行うことができます。

ここにデモがあります

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        string actualdata = string.Empty;
        char[] entereddata = textBox1.Text.ToCharArray();
        foreach (char aChar in entereddata.AsEnumerable())
        {
            if (Char.IsDigit(aChar))
            {
                actualdata = actualdata + aChar;
                // MessageBox.Show(aChar.ToString());
            }
            else
            {
                MessageBox.Show(aChar + " is not numeric");
                actualdata.Replace(aChar, ' ');
                actualdata.Trim();
            }
        }
        textBox1.Text = actualdata;
    }

おかげで、非常に便利です。
Kiran RS

2

この質問に対する現在の回答の多くは、手動で入力テキストを解析しているようです。特定の組み込み数値型(intまたはdouble)を探している場合は、作業をその型のTryParseメソッドに委任しないでください。例えば:

public class IntTextBox : TextBox
{
    string PreviousText = "";
    int BackingResult;

    public IntTextBox()
    {
        TextChanged += IntTextBox_TextChanged;
    }

    public bool HasResult { get; private set; }

    public int Result
    {
        get
        {
            return HasResult ? BackingResult : default(int);
        }
    }

    void IntTextBox_TextChanged(object sender, EventArgs e)
    {
        HasResult = int.TryParse(Text, out BackingResult);

        if (HasResult || string.IsNullOrEmpty(Text))
        {
            // Commit
            PreviousText = Text;
        }
        else
        {
            // Revert
            var changeOffset = Text.Length - PreviousText.Length;
            var previousSelectionStart =
                Math.Max(0, SelectionStart - changeOffset);

            Text = PreviousText;
            SelectionStart = previousSelectionStart;
        }
    }
}

より一般的なものを必要とするが、Visual Studioのデザイナーと互換性がある場合:

public class ParsableTextBox : TextBox
{
    TryParser BackingTryParse;
    string PreviousText = "";
    object BackingResult;

    public ParsableTextBox()
        : this(null)
    {
    }

    public ParsableTextBox(TryParser tryParse)
    {
        TryParse = tryParse;

        TextChanged += ParsableTextBox_TextChanged;
    }

    public delegate bool TryParser(string text, out object result);

    public TryParser TryParse
    {
        set
        {
            Enabled = !(ReadOnly = value == null);

            BackingTryParse = value;
        }
    }

    public bool HasResult { get; private set; }

    public object Result
    {
        get
        {
            return GetResult<object>();
        }
    }

    public T GetResult<T>()
    {
        return HasResult ? (T)BackingResult : default(T);
    }

    void ParsableTextBox_TextChanged(object sender, EventArgs e)
    {
        if (BackingTryParse != null)
        {
            HasResult = BackingTryParse(Text, out BackingResult);
        }

        if (HasResult || string.IsNullOrEmpty(Text))
        {
            // Commit
            PreviousText = Text;
        }
        else
        {
            // Revert
            var changeOffset = Text.Length - PreviousText.Length;
            var previousSelectionStart =
                Math.Max(0, SelectionStart - changeOffset);

            Text = PreviousText;
            SelectionStart = previousSelectionStart;
        }
    }
}

最後に、完全に汎用的なものが必要で、Designerのサポートを気にしない場合:

public class ParsableTextBox<T> : TextBox
{
    TryParser BackingTryParse;
    string PreviousText;
    T BackingResult;

    public ParsableTextBox()
        : this(null)
    {
    }

    public ParsableTextBox(TryParser tryParse)
    {
        TryParse = tryParse;

        TextChanged += ParsableTextBox_TextChanged;
    }

    public delegate bool TryParser(string text, out T result);

    public TryParser TryParse
    {
        set
        {
            Enabled = !(ReadOnly = value == null);

            BackingTryParse = value;
        }
    }

    public bool HasResult { get; private set; }

    public T Result
    {
        get
        {
            return HasResult ? BackingResult : default(T);
        }
    }

    void ParsableTextBox_TextChanged(object sender, EventArgs e)
    {
        if (BackingTryParse != null)
        {
            HasResult = BackingTryParse(Text, out BackingResult);
        }

        if (HasResult || string.IsNullOrEmpty(Text))
        {
            // Commit
            PreviousText = Text;
        }
        else
        {
            // Revert
            var changeOffset = Text.Length - PreviousText.Length;
            var previousSelectionStart =
                Math.Max(0, SelectionStart - changeOffset);

            Text = PreviousText;
            SelectionStart = previousSelectionStart;
        }
    }
}

2

負の数も含め、整数と浮動小数点の両方を受け入れる必要があります。

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    // Text
    string text = ((Control) sender).Text;

    // Is Negative Number?
    if (e.KeyChar == '-' && text.Length == 0)
    {
        e.Handled = false;
        return;
    }

    // Is Float Number?
    if (e.KeyChar == '.' && text.Length > 0 && !text.Contains("."))
    {
        e.Handled = false;
        return;
    }

    // Is Digit?
    e.Handled = (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar));
}

2

これは私のアプローチです:

  1. linqの使用(フィルターの変更が簡単)
  2. プルーフコードのコピー/貼り付け
  3. 禁止された文字を押してもキャレットの位置を保持します
  4. 左ゼロを受け入れる
  5. と任意のサイズ番号

    private void numeroCuenta_TextChanged(object sender, EventArgs e)
    {
        string org = numeroCuenta.Text;
        string formated = string.Concat(org.Where(c => (c >= '0' && c <= '9')));
        if (formated != org)
        {
            int s = numeroCuenta.SelectionStart;
            if (s > 0 && formated.Length > s && org[s - 1] != formated[s - 1]) s--;
            numeroCuenta.Text = formated;
            numeroCuenta.SelectionStart = s;
        }
    }

2

Fabio Iottiの回答に記載されているアプローチを使用して、より一般的なソリューションを作成しました。

public abstract class ValidatedTextBox : TextBox {
    private string m_lastText = string.Empty;
    protected abstract bool IsValid(string text);
    protected sealed override void OnTextChanged(EventArgs e) {
        if (!IsValid(Text)) {
            var pos = SelectionStart - Text.Length + m_lastText.Length;
            Text = m_lastText;
            SelectionStart = Math.Max(0, pos);
        }
        m_lastText = Text;
        base.OnTextChanged(e);
    }
}

"ValidatedTextBox"。重要な検証動作がすべて含まれています。あとは、このクラスから継承して、必要な検証ロジックで "IsValid"メソッドをオーバーライドするだけです。たとえば、このクラスを使用すると、特定の正規表現に一致する文字列のみを受け入れる "RegexedTextBox"を作成できます。

public abstract class RegexedTextBox : ValidatedTextBox {
    private readonly Regex m_regex;
    protected RegexedTextBox(string regExpString) {
        m_regex = new Regex(regExpString);
    }
    protected override bool IsValid(string text) {
        return m_regex.IsMatch(Text);
    }
}

その後、「RegexedTextBox」クラスから継承して、「PositiveNumberTextBox」および「PositiveFloatingPointNumberTextBox」コントロールを簡単に作成できます。

public sealed class PositiveNumberTextBox : RegexedTextBox {
    public PositiveNumberTextBox() : base(@"^\d*$") { }
}

public sealed class PositiveFloatingPointNumberTextBox : RegexedTextBox {
    public PositiveFloatingPointNumberTextBox()
        : base(@"^(\d+\" + CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator + @")?\d*$") { }
}

1

死者を目覚めさせて申し訳ありませんが、誰かがこれが将来の参照に役立つと思うかもしれないと思いました。

ここで私はそれを処理する方法です。浮動小数点数を処理しますが、整数用に簡単に変更できます。

基本的にはあなただけ押すことができます0 - 9

の前に0を1つだけ持つことができますます。

他のすべての文字は無視され、カーソル位置は維持されます。

    private bool _myTextBoxChanging = false;

    private void myTextBox_TextChanged(object sender, EventArgs e)
    {
        validateText(myTextBox);
    }

    private void validateText(TextBox box)
    {
        // stop multiple changes;
        if (_myTextBoxChanging)
            return;
        _myTextBoxChanging = true;

        string text = box.Text;
        if (text == "")
            return;
        string validText = "";
        bool hasPeriod = false;
        int pos = box.SelectionStart;
        for (int i = 0; i < text.Length; i++ )
        {
            bool badChar = false;
            char s = text[i];
            if (s == '.')
            {
                if (hasPeriod)
                    badChar = true;
                else
                    hasPeriod = true;
            }
            else if (s < '0' || s > '9')
                badChar = true;

            if (!badChar)
                validText += s;
            else
            {
                if (i <= pos)
                    pos--;
            }
        }

        // trim starting 00s
        while (validText.Length >= 2 && validText[0] == '0')
        {
            if (validText[1] != '.')
            {
                validText = validText.Substring(1);
                if (pos < 2)
                    pos--;
            }
            else
                break;
        }

        if (pos > validText.Length)
            pos = validText.Length;
        box.Text = validText;
        box.SelectionStart = pos;
        _myTextBoxChanging = false;
    }

以下は、すばやく変更されたintバージョンです。

    private void validateText(TextBox box)
    {
        // stop multiple changes;
        if (_myTextBoxChanging)
            return;
        _myTextBoxChanging = true;

        string text = box.Text;
        if (text == "")
            return;
        string validText = "";
        int pos = box.SelectionStart;
        for (int i = 0; i < text.Length; i++ )
        {
            char s = text[i];
            if (s < '0' || s > '9')
            {
                if (i <= pos)
                    pos--;
            }
            else
                validText += s;
        }

        // trim starting 00s 
        while (validText.Length >= 2 && validText.StartsWith("00")) 
        { 
            validText = validText.Substring(1); 
            if (pos < 2) 
                pos--; 
        } 

        if (pos > validText.Length)
            pos = validText.Length;
        box.Text = validText;
        box.SelectionStart = pos;
        _myTextBoxChanging = false;
    }

2
このソリューションは、警告付きでホイールを再発明しています。ローカリゼーションなど。
Julien Guertault、

1

これはコピーアンドペースト、ドラッグアンドドロップ、キーダウンで機能し、オーバーフローを防ぎ、非常に簡単です。

public partial class IntegerBox : TextBox 
{
    public IntegerBox()
    {
        InitializeComponent();
        this.Text = 0.ToString();
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }

    private String originalValue = 0.ToString();

    private void Integerbox_KeyPress(object sender, KeyPressEventArgs e)
    {
        originalValue = this.Text;
    }

    private void Integerbox_TextChanged(object sender, EventArgs e)
    {
        try
        {
            if(String.IsNullOrWhiteSpace(this.Text))
            {
                this.Text = 0.ToString();
            }
            this.Text = Convert.ToInt64(this.Text.Trim()).ToString();
        }
        catch (System.OverflowException)
        {
            MessageBox.Show("Value entered is to large max value: " + Int64.MaxValue.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            this.Text = originalValue;
        }
        catch (System.FormatException)
        {                
            this.Text = originalValue;
        }
        catch (System.Exception ex)
        {
            this.Text = originalValue;
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK , MessageBoxIcon.Error);
        }
    }       
}

1

ユーザーが無効なテキストをに貼り付けることができることを忘れないでくださいTextBox

それを制限したい場合は、以下のコードに従ってください:

private void ultraTextEditor1_TextChanged(object sender, EventArgs e)
{
    string append="";
    foreach (char c in ultraTextEditor1.Text)
    {
        if ((!Char.IsNumber(c)) && (c != Convert.ToChar(Keys.Back)))
        {

        }
        else
        {
            append += c;
        }
    }

    ultraTextEditor1.Text = append;
}   

1

私はまた、テキストボックスの数字のみをチェックする最良の方法を探していました、そしてキープレスの問題は、右クリックまたはクリップボードによるコピー貼り付けをサポートしていないため、カーソルがテキストフィールドを離れるときに検証するこのコードを考案し、それもチェックしました空のフィールド。(newguyの適応バージョン)

private void txtFirstValue_MouseLeave(object sender, EventArgs e)
{
    int num;
    bool isNum = int.TryParse(txtFirstValue.Text.Trim(), out num);

    if (!isNum && txtFirstValue.Text != String.Empty)
    {
        MessageBox.Show("The First Value You Entered Is Not a Number, Please Try Again", "Invalid Value Detected", MessageBoxButtons.OK, MessageBoxIcon.Error);
        txtFirstValue.Clear();
    }
}

MouseLeaveは、使用するイベントにとって本当に悪い選択のようです。
LarsTech

@LarsTechは、テキストが変更されたと思っていても、ユーザーがエラーに気付いて修正しようとしても、エラーメッセージボックスが表示されることがあります。この場合に最適なイベントは何だと思いますか?
Alston Antony、

@AlstonAntony遅いコメント、私は知っています。しかし、右クリックでアクティブになる単純なクリックイベントで十分でしょうか。
宝井

0
int Number;
bool isNumber;
isNumber = int32.TryPase(textbox1.text, out Number);

if (!isNumber)
{ 
    (code if not an integer);
}
else
{
    (code if an integer);
}

0

3ソリューション

1)

//Add to the textbox's KeyPress event
//using Regex for number only textBox

private void txtBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), "\\d+"))
e.Handled = true;
}

2)msdnの別のソリューション

// Boolean flag used to determine when a character other than a number is entered.
private bool nonNumberEntered = false;
// Handle the KeyDown event to determine the type of character entered into the     control.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
    // Determine whether the keystroke is a number from the keypad.
    if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
    {
        // Determine whether the keystroke is a backspace.
        if (e.KeyCode != Keys.Back)
        {
            // A non-numerical keystroke was pressed.
            // Set the flag to true and evaluate in KeyPress event.
            nonNumberEntered = true;
        }
    }
}

}

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (nonNumberEntered == true)
    {
       MessageBox.Show("Please enter number only..."); 
       e.Handled = true;
    }
}

ソース http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress(v=VS.90).aspx

3)MaskedTextBoxの使用:http ://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx


0

ボタンをクリックすると、テキストボックスのテキストをforループで確認できます。

char[] c = txtGetCustomerId.Text.ToCharArray();
bool IsDigi = true;

for (int i = 0; i < c.Length; i++)
     {
       if (c[i] < '0' || c[i] > '9')
      { IsDigi = false; }
     }
 if (IsDigi)
    { 
     // do something
    }

0

より簡単な答え:

_textBox.TextChanged += delegate(System.Object o, System.EventArgs e)
{
    TextBox _tbox = o as TextBox;
    _tbox.Text = new string(_tbox.Text.Where(c => (char.IsDigit(c)) || (c == '.')).ToArray());
};
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.