Comment créer une boîte de texte qui n'accepte que les nombres?

j'ai une application Windows forms avec un contrôle textbox que je veux seulement accepter des valeurs entières. Dans le passé, j'ai fait ce genre de validation en surchargeant L'événement KeyPress et en enlevant simplement les caractères qui ne correspondaient pas à la spécification. J'ai regardé le contrôle MaskedTextBox mais j'aimerais une solution plus générale qui pourrait fonctionner avec peut-être une expression régulière, ou dépendre des valeurs des autres contrôles.

idéalement, cela se comporterait de telle sorte que la pression sur un le caractère non numérique ne produirait pas de résultat ou fournirait immédiatement à l'utilisateur une rétroaction sur le caractère non valide.

499
demandé sur Mykroft 2009-01-21 00:55:01

30 réponses

deux options:

  1. utilisez un NumericUpDown à la place. NumericUpDown fait le filtrage pour vous, ce qui est bien. Bien sûr, il donne également aux utilisateurs la capacité de frapper les flèches haut et bas du clavier pour incrémenter et décrémenter la valeur actuelle.

  2. Gérer les événements clavier appropriés pour empêcher tout autre entrée que numérique. J'ai eu du succès avec ce deux les gestionnaires d'événements sur une zone de texte standard:

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

vous pouvez supprimer le contrôle pour '.' (et le contrôle suivant pour plus d'un '.' ) si votre boîte de texte ne devrait pas permettre des décimales. Vous pouvez également ajouter un contrôle pour '-' si votre boîte de texte devrait permettre des valeurs négatives.

Si vous souhaitez limiter l'utilisateur pour le nombre de chiffres, utilisez: textBox1.MaxLength = 2; // this will allow the user to enter only 2 digits

681
répondu Matt Hamilton 2014-10-14 15:40:21

et juste parce qu'il est toujours plus amusant de faire des choses dans une ligne...

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

NOTE: cela n'empêche pas un utilisateur de copier / coller dans cette zone de texte. Ce n'est pas une façon sûre d'épurer vos données.

119
répondu BFree 2009-01-20 22:24:54

je présume, d'après le contexte et les balises que vous avez utilisées, que vous écrivez une application .NET c#. Dans ce cas, vous pouvez vous abonner à l'événement text changed et valider chaque touche.

    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);
        }
    }
42
répondu Anthony D 2017-01-16 13:06:04

voici un simple contrôle personnalisé de Winforms standalone, dérivé de la TextBox standard, qui ne permet que le système.Entrée Int32 (il pourrait être facilement adapté pour d'autres types tels que le système.Int64, etc.). Il supporte les opérations de copie / coller et les nombres négatifs:

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

mise à Jour de 2017 : Ma première réponse a certaines valeurs par défaut:

  • vous pouvez taper quelque chose qui est plus long qu'un entier d'un type donné (pour l'exemple 2147483648 est supérieur à Int32.MaxValue);
  • plus généralement, il n'y a pas de validation réelle du résultat de ce qui a été dactylographié;
  • il ne gère int32, vous aurez à écrire spécifique TextBox derivated control pour chaque type (Int64, etc.)

donc j'ai trouvé une autre version qui est plus générique, qui supporte encore le copier/coller, + et - signer, etc.

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

pour Int32, vous pouvez soit en dériver, comme ceci:

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

ou W/O derivation, utiliser le nouvel événement TextValidating comme ceci:

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

mais ce qui est bien c'est que ça fonctionne avec n'importe quelle chaîne, et n'importe quelle routine de validation.

29
répondu Simon Mourier 2017-08-31 22:03:14

C'est exactement pour cela que les événements validés/validés ont été conçus.

Voici l'article du MSDN sur le sujet: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx

Le TL;DR version: vérifier l' .La propriété de texte dans l'événement de validation et de mettre e.Cancel=True quand les données sont invalides.

quand vous définissez E. Cancel=True, l'utilisateur ne peut pas quitter le champ, mais vous aurez besoin de leur donner une sorte de rétroaction que quelque chose ne va pas. Je change la couleur de fond de la boîte en rouge clair pour indiquer un problème. Assurez-vous de revenir à SystemColors.Window lorsque la validation est appelée avec une bonne valeur.

17
répondu TomXP411 2013-07-27 00:40:10

Essayer MaskedTextBox . Il prend un format de masque simple de sorte que vous pouvez limiter l'entrée à des nombres ou des dates ou n'importe quoi.

13
répondu Andrew Kennan 2009-01-20 22:01:14

vous pouvez utiliser l'événement TextChanged 151930920"

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();
    }
}
11
répondu Davit Tvildiani 2014-11-05 08:39:55

j'ai travaillé sur une collection de composants pour compléter les choses manquantes dans WinForms, voici: formulaires avancés

en particulier, il s'agit de la classe pour une boîte de texte Regex

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

ajouter simplement quelque chose comme myNumbericTextBox.RegexString = "^(\d+|)$"; devrait suffire.

5
répondu Fabio Iotti 2015-02-25 08:23:39

j'ai fait quelque chose pour cela sur CodePlex .

il fonctionne en interceptant l'événement TextChanged. Si le résultat est un bon nombre, il sera stocké. Si quelque chose ne va pas, la dernière bonne valeur sera restaurée. La source est un peu trop grande pour être publiée ici, mais voici un lien vers la classe qui gère le cœur de cette logique.

4
répondu GvS 2009-01-20 22:18:13

cela pourrait être utile. Il permet des valeurs numériques "réelles", y compris les points décimaux appropriés et les signes précédant plus ou moins. Appelez - le depuis L'événement de KeyPress correspondant.

       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;
    }
4
répondu Roger Garrett 2012-08-08 20:06:38

utilisez simplement ce code dans la boîte de texte:

private void textBox1_TextChanged(object sender, EventArgs e)
{

    double parsedValue;

    if (!double.TryParse(textBox1.Text, out parsedValue))
    {
        textBox1.Text = "";
    }
}
4
répondu saurabh27 2015-03-13 21:24:16

dans notre page Web avec la définition de textbox nous pouvons ajouter un onkeypress événement pour accepter seulement des nombres. Il ne montrera aucun message mais il vous empêchera de la mauvaise entrée. Cela a fonctionné pour moi, l'utilisateur ne pouvait rien entrer sauf le nombre.

<asp:TextBox runat="server" ID="txtFrom"
     onkeypress="if(isNaN(String.fromCharCode(event.keyCode))) return false;">
4
répondu ssah 2016-05-10 21:43:20

utilisez simplement une commande NumericUpDown et réglez la visibilité des boutons laids up down à false .

numericUpDown1.Controls[0].Visible = false;

NumericUpDown est en fait un ensemble de contrôles contenant une "boîte de spin" (boutons vers le haut vers le bas), une boîte de texte et un peu de code pour valider et changer-jangle il tous ensemble.

Marquage:

YourNumericUpDown.Controls[0].visible = false 

masquera les boutons tout en gardant le code sous-jacent actif.

alors que n'étant pas une solution évidente, c'est simple et efficace. .Controls[1] cacherait la partie de la zone de texte si vous vouliez le faire à la place.

3
répondu user2163234 2018-02-06 11:21:41

vous pouvez utiliser TextChanged / KeyPress event, utiliser un regex pour filtrer sur les nombres et prendre des mesures.

2
répondu Perpetualcoder 2009-01-20 21:59:29
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;
        }
    }
}

l'essayer c'est très simple

2
répondu rithish 2013-10-18 12:50:02

regardez gérer les Entrées en WinForm

j'ai posté ma solution qui utilise les événements ProcessCmdKey et OnKeyPress sur la textbox. Les commentaires vous montrent comment utiliser une Regex pour vérifier le clavier et bloquer / autoriser de manière appropriée.

2
répondu benPearce 2017-05-23 11:54:59

Salut Vous pouvez faire quelque chose comme ça dans l'événement textchanged de la textbox.

voici une démo

    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;
    }
2
répondu Chandan Kumar 2014-01-05 14:12:05

il semble que beaucoup des réponses actuelles à cette question sont manuellement parsing le texte d'entrée. Si vous cherchez un type numérique spécifique intégré (par exemple int ou double ), pourquoi ne pas simplement déléguer le travail à la méthode TryParse de ce type? Par exemple:

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

si vous voulez quelque chose de plus générique mais toujours compatible avec le concepteur de 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;
        }
    }
}

et enfin, si vous voulez quelque chose générique et ne se soucient pas de la prise en charge du Concepteur:

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
répondu William 2014-07-23 22:59:26

les entiers et les flotteurs doivent être acceptés, y compris les nombres négatifs.

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
répondu nabeghe 2018-02-06 12:04:23

en utilisant l'approche décrite dans réponse de Fabio Iotti j'ai créé une solution plus générique:

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", qui contient tous les comportements de validation non trivial. Tout ce qui reste à faire est d'hériter de cette classe et d'outrepasser la méthode "IsValid" avec quelle que soit la logique de validation requise. Par exemple, en utilisant cette classe, il est possible de créer "RegexedTextBox" qui n'acceptera que les chaînes qui correspondent à des expression courante:

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

après cela, en héritant de la classe" RegexedTextBox", nous pouvons facilement créer "PositiveNumberTextBox" et" PositiveFloatingPointNumberTextBox "contrôles:

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

public sealed class PositiveFloatingPointNumberTextBox : RegexedTextBox {
    public PositiveFloatingPointNumberTextBox()
        : base(@"^(\d+\" + CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator + @")?\d*$") { }
}
2
répondu PolarBear 2018-06-18 21:31:56

désolé de réveiller les morts, mais j'ai pensé que quelqu'un pourrait trouver cela utile pour une référence future.

voilà comment je gère ça. Il gère les nombres à virgule flottante, mais peut facilement être modifié pour les entiers.

en gros, vous ne pouvez appuyer que sur 0 - 9 et .

Vous ne pouvez avoir qu'un 0 avant le .

tous les autres caractères sont ignorés et la position du curseur est maintenue.

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

Voici une version int rapidement modifiée:

    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;
    }
1
répondu yardape 2011-10-31 04:54:50

Je m'en occuperais dans le cas du KeyDown.

void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            char c = Convert.ToChar(e.PlatformKeyCode);
            if (!char.IsDigit(c))
            {
                e.Handled = true;
            }
        }
1
répondu Shaz 2012-09-16 23:57:22

celui-ci fonctionne avec Copier et coller, glisser et déposer, la touche vers le bas, empêche le débordement et est assez simple

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
répondu user1626874 2013-09-17 13:50:04

n'oubliez pas qu'un utilisateur peut coller un texte non valide dans un TextBox .

si vous voulez restreindre cela, suivez le code ci-dessous:

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
répondu Divya 2018-02-06 11:53:19

j'étais également à la recherche de la meilleure façon de vérifier seulement les numéros dans la boîte de texte et le problème avec keypress était qu'il ne supporte pas le copier-coller par le clic droit ou le bloc-notes alors est venu avec ce code qui valide le curseur quand quitte le champ de texte et aussi il vérifie pour le champ vide. (adaptation de 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();
    }
}
1
répondu Alston Antony 2018-02-06 11:55:46
int Number;
bool isNumber;
isNumber = int32.TryPase(textbox1.text, out Number);

if (!isNumber)
{ 
    (code if not an integer);
}
else
{
    (code if an integer);
}
0
répondu newguy 2011-11-20 05:35:22

3 solution

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) une autre solution de 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) en utilisant la MaskedTextBox: http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx

0
répondu modest and cute girl 2012-08-09 02:14:53

dans le clic de bouton vous pouvez vérifier le texte de la boîte de texte pour boucle:

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
répondu Shaahin 2013-08-25 11:49:10

réponse plus simple:

_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());
};
0
répondu micahhoover 2013-09-24 21:01:58

FAIL-SAFE et méthode simple" recursive", qui peut être utilisé avec plusieurs boîtes de textes.

il bloque les mauvais caractères dactylographiés sur le clavier ainsi que les valeurs collées, etc. Il n'accepte que les nombres entiers, et la longueur du nombre maximum est la longueur maximale d'un type de chaîne de caractères (qui est int, vraiment long!)

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;
    }
 }
0
répondu W0lfw00ds 2014-04-09 13:58:45