net - how to make textbox accept only numbers in c#




كيف أقوم بإنشاء مربع نص لا يقبل سوى الأرقام؟ (20)

لدي تطبيق نماذج إطارات يحتوي على عنصر تحكم في مربع النص وأريد قبول قيم عدد صحيح فقط. في الماضي ، قمت بهذا النوع من التحقق من خلال تحميل حدث KeyPress وإزالة الأحرف التي لا تتوافق مع المواصفات. لقد نظرت إلى عنصر التحكم MaskedTextBox لكني أرغب في حل أكثر عمومية يمكن أن يعمل مع تعبير عادي ، أو يعتمد على قيم عناصر التحكم الأخرى.

من الناحية المثالية ، قد يتصرف هذا بحيث يؤدي الضغط على حرف غير رقمي إلى أي نتيجة أو تزويد المستخدم فوراً بتعليقات حول الحرف غير الصالح.


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;
    }
}

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

3) باستخدام MaskedTextBox: MaskedTextBox


آسف لإيقاظ الموتى ، لكنني اعتقدت أن شخصًا ما قد يجد هذا مفيدًا للرجوع إليه في المستقبل.

هنا كيف أتعامل معها. يتعامل مع أرقام النقطة العائمة ، ولكن يمكن تعديلها بسهولة للأعداد الصحيحة.

في الأساس يمكنك فقط الضغط على 0 - 9 و .

يمكنك الحصول على 0 واحد فقط قبل .

يتم تجاهل جميع الأحرف الأخرى والحفاظ على موضع المؤشر.

    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;
    }

ألق نظرة على معالجة الإدخال في WinForm

لقد قمت بنشر الحل الخاص بي الذي يستخدم الأحداث ProcessCmdKey و OnKeyPress في مربع النص. توضح لك التعليقات كيفية استخدام Regex للتحقق من الضغط على المفتاح والحظر / السماح بشكل مناسب.


أنا أحب رمز مقتضب

    private void xmm_textbox_KeyPress(object sender, KeyPressEventArgs e) {
        double x;
        e.Handled = !double.TryParse(((TextBox)sender).Text, out x);
    }

ببساطة استخدام هذا الرمز في مربع النص:

private void textBox1_TextChanged(object sender, EventArgs e)
{

    double parsedValue;

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

حاول MaskedTextBox . يتطلب تنسيق قناع بسيط بحيث يمكنك تحديد الإدخال إلى أرقام أو تواريخ أو أي شيء.


في زر النقر ، يمكنك التحقق من نص مربع النص عن حلقة:

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
    }

في صفحة الويب لدينا مع تعريف مربع النص ، يمكننا إضافة حدث onkeypress لقبول الأرقام فقط. لن تظهر أي رسالة ولكنها ستمنعك من إدخال خاطئ. عملت لي ، لا يمكن للمستخدم إدخال أي شيء باستثناء الرقم.

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

كنت أود التعامل معها في الحدث KeyDown.

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

لا تنس أنه يمكن للمستخدم لصق نص غير صالح في 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;
}   

لقد كنت أعمل على مجموعة من المكونات لإكمال الأشياء المفقودة في WinForms ، ومن هنا: نماذج متقدمة

على وجه الخصوص هذا هو الطبقة لـ 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+|)$"; يجب أن يكفي.


ما عليك سوى استخدام NumericUpDown تحكم NumericUpDown وتعيين تلك الرؤى القبيحة لأسفل إلى الأزرار.

numericUpDown1.Controls[0].Visible = false;

NumericUpDown هو في الواقع مجموعة من الضوابط التي تحتوي على "مربع تدور" (حتى أسفل الأزرار) ، ومربع النص وبعض التعليمات البرمجية للتحقق من صحة و jange كل ذلك معا.

العلامات:

YourNumericUpDown.Controls[0].visible = false 

سوف يخفي الأزرار مع الحفاظ على الكود الأساسي نشطًا.

في حين لا يكون حل واضح فهي بسيطة وفعالة. سوف تخفي .Controls[1] جزء مربع النص إذا أردت القيام بذلك بدلاً من ذلك.


هذا قد يكون مفيدا. يسمح بقيم رقمية "حقيقية" ، بما في ذلك النقاط العشرية المناسبة وعلامات زائد أو ناقص السابقة. اتصل بها من داخل الحدث 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;
    }

هذا هو بالضبط ما تم تصميمه للأحداث المصادق عليها / التحقق من الصحة.

فيما يلي مقالة MSDN حول الموضوع: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx

إصدار TL ؛ DR: تحقق من خاصية .Text في حدث e.Cancel=True واضبط e.Cancel=True عندما تكون البيانات غير صالحة.

عندما تقوم بتعيين e.Cancel = True ، لا يمكن للمستخدم ترك هذا الحقل ، ولكنك ستحتاج إلى إعطاءهم نوعًا ما من التعليقات التي تشير إلى خطأ ما. أقوم بتغيير لون خلفية الصندوق إلى الأحمر الفاتح للإشارة إلى وجود مشكلة. تأكد من تعيينها مرة أخرى إلى SystemColors.Window عندما يتم استدعاء Validating مع قيمة جيدة.


هنا هو عنصر تحكم مستقل بسيط مستقل Winforms ، مشتقة من TextBox القياسية ، التي تسمح فقط بإدخال 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);
    }
}

أو w / o derivation ، استخدم الحدث TextValiding الجديد مثل:

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

ولكن ما هو لطيف هو أنه يعمل مع أي سلسلة ، وأي روتين التحقق من الصحة.


ولأنه دائمًا ما يكون أكثر متعة للقيام بالأشياء في سطر واحد ...

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

ملاحظة: هذا لا يمنع مستخدم من نسخ / لصق في مربع النص هذا. انها ليست وسيلة آمنة فاشلة لتطهير البيانات الخاصة بك.


يجب قبول كل من الأعداد الصحيحة والعوام ، بما في ذلك الأرقام السالبة.

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));
}

يمكنك استخدام الحدث TextChanged / Keypress ، استخدم regex لتصفية الأرقام واتخاذ بعض الإجراءات.


FAIL-SAFE وطريقة "تكرارية" بسيطة ، والتي يمكن استخدامها مع مربعات نصوص متعددة.

فهو يقوم بحجب الحروف المكتوبة على لوحة المفاتيح الخاطئة وكذلك القيم الملصقة وما إلى ذلك. يقبل فقط الأرقام الصحيحة ، والحد الأقصى لطول العدد هو الحد الأقصى لطول نوع السلسلة (وهو int ، حقًا طويل!)

public void Check_If_Int_On_TextChanged(object sender, EventArgs e)
{
   // This method checks that each inputed character is a number. Any non-numeric
   // characters are removed from the text

   TextBox textbox = (TextBox)sender;

   // If the text is empty, return
   if (textbox.Text.Length == 0) { return; }

   // Check the new Text value if it's only numbers
   byte parsedValue;
   if (!byte.TryParse(textbox.Text[(textbox.Text.Length - 1)].ToString(), out parsedValue))
   {
      // Remove the last character as it wasn't a number
      textbox.Text = textbox.Text.Remove((textbox.Text.Length - 1));

      // Move the cursor to the end of text
      textbox.SelectionStart = textbox.Text.Length;
    }
 }

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

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






textbox