web-dev-qa-db-fra.com

Autoriser uniquement des caractères spécifiques dans la zone de texte

Comment puis-je autoriser uniquement certains caractères dans une zone de texte Visual C #? Les utilisateurs doivent pouvoir saisir les caractères suivants dans une zone de texte et tout le reste doit être bloqué: 0-9, +, -, /, *, (,).

J'ai utilisé Google pour rechercher ce problème, mais les seules solutions possibles sont de n'autoriser que les caractères alphabétiques, uniquement les caractères numériques ou d'interdire certains caractères. Ce que je veux, ce n'est pas interdire certains caractères, je veux tout interdire par défaut, à l'exception des caractères que j'ai mis dans le code.

15
Annoying Bot

Comme mentionné dans un commentaire (et une autre réponse que j'ai tapée), vous devez enregistrer un gestionnaire d'événements pour intercepter l'événement de frappe au clavier ou de frappe sur une zone de texte. En effet, TextChanged n'est déclenché que lorsque la zone de texte perd le focus.

La regex ci-dessous vous permet de faire correspondre les caractères que vous souhaitez autoriser

Regex regex = new Regex(@"[0-9+\-\/\*\(\)]");
MatchCollection matches = regex.Matches(textValue);

et cela fait le contraire et attrape les caractères qui ne sont pas autorisés

Regex regex = new Regex(@"[^0-9^+^\-^\/^\*^\(^\)]");
MatchCollection matches = regex.Matches(textValue);

Je ne suppose pas qu'il y aura une seule correspondance car quelqu'un pourrait coller du texte dans la zone de texte. dans ce cas, capture textchanged

textBox1.TextChanged += new TextChangedEventHandler(textBox1_TextChanged);
private void textBox1_TextChanged(object sender, EventArgs e)
{
    Regex regex = new Regex(@"[^0-9^+^\-^\/^\*^\(^\)]");
    MatchCollection matches = regex.Matches(textBox1.Text);
    if (matches.Count > 0) {
       //tell the user
    }
}

et pour valider les pressions simples

textBox1.KeyPress += new KeyPressEventHandler(textBox1_KeyPress);
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
    // Check for a naughty character in the KeyDown event.
    if (System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), @"[^0-9^+^\-^\/^\*^\(^\)]"))
    {
        // Stop the character from being entered into the control since it is illegal.
        e.Handled = true;
    }
}
23
Paul D'Ambra

Vous devez vous abonner à l'événement KeyDown dans la zone de texte. Alors quelque chose comme ceci:

private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
    if (!char.IsControl(e.KeyChar) 
       && !char.IsDigit(e.KeyChar) 
       && e.KeyChar != '.' && e.KeyChar != '+' && e.KeyChar != '-'
       && e.KeyChar != '(' && e.KeyChar != ')' && e.KeyChar != '*' 
       && e.KeyChar != '/')
    {
        e.Handled = true;
        return;
    }
    e.Handled=false;
    return;
}

Il est important de savoir que si vous modifiez la propriété Handled en true, elle ne traitera pas la frappe. Réglez-le sur false volonté.

10
Icemanind

Vous pouvez probablement utiliser l'événement KeyDown , événement KeyPress ou événement KeyUp . Je voudrais d'abord essayer l'événement KeyDown, je pense.

Vous pouvez définir la propriété Handled des arguments d'événement pour qu'elle cesse de gérer l'événement.

1
Maarten

Intercepter l'événement KeyPressed est à mon avis une bonne solution solide. Faites attention aux caractères du code de déclenchement (e.KeyChar inférieur à 32) si vous utilisez un RegExp.

Mais de cette manière, il est toujours possible d’injecter des caractères hors de portée chaque fois que l’utilisateur colle du texte à partir du presse-papiers. Malheureusement, je n'ai pas trouvé les événements appropriés dans le Presse-papiers pour résoudre ce problème.

Une solution étanche consiste donc à intercepter TextBox.TextChanged. Voici parfois le caractère original hors de portée visible, pendant une courte période. Je recommande d'implémenter les deux.

using System.Text.RegularExpressions;

private void Form1_Shown(object sender, EventArgs e)
{
    filterTextBoxContent(textBox1);
}


string pattern = @"[^0-9^+^\-^/^*^(^)]";

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if(e.KeyChar >= 32 && Regex.Match(e.KeyChar.ToString(), pattern).Success) { e.Handled = true; }
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    filterTextBoxContent(textBox1);
}

private bool filterTextBoxContent(TextBox textBox)
{
    string text = textBox.Text;

    MatchCollection matches = Regex.Matches(text, pattern);
    bool matched = false;

    int selectionStart = textBox.SelectionStart;
    int selectionLength = textBox.SelectionLength;

    int leftShift = 0;
    foreach (Match match in matches)
    {
        if (match.Success && match.Captures.Count > 0)
        {
            matched = true;
            Capture capture = match.Captures[0];

            int captureLength = capture.Length;
            int captureStart = capture.Index - leftShift;
            int captureEnd = captureStart + captureLength;

            int selectionEnd = selectionStart + selectionLength;

            text = text.Substring(0, captureStart) + text.Substring(captureEnd, text.Length - captureEnd);

            textBox.Text = text;

            int boundSelectionStart = selectionStart < captureStart ? -1 : (selectionStart < captureEnd ? 0 : 1);
            int boundSelectionEnd = selectionEnd < captureStart ? -1 : (selectionEnd < captureEnd ? 0 : 1);

            if (boundSelectionStart == -1)
            {
                if (boundSelectionEnd == 0)
                {
                    selectionLength -= selectionEnd - captureStart;
                }
                else if (boundSelectionEnd == 1)
                {
                    selectionLength -= captureLength;
                }
            }
            else if (boundSelectionStart == 0)
            {
                if (boundSelectionEnd == 0)
                {
                    selectionStart = captureStart;
                    selectionLength = 0;
                }
                else if (boundSelectionEnd == 1)
                {
                    selectionStart = captureStart;
                    selectionLength -= captureEnd - selectionStart;
                }
            }
            else if (boundSelectionStart == 1)
            {
                selectionStart -= captureLength;
            }

            leftShift++;
        }
    }

    textBox.SelectionStart = selectionStart;
    textBox.SelectionLength = selectionLength;

    return matched;
}
0
Martin Wantke

Pour votre événement de validation IMO, la méthode la plus simple consisterait à utiliser un tableau de caractères pour valider les caractères de la zone de texte. Vrai - itérer et valider n’est pas particulièrement efficace, mais c’est simple.

Vous pouvez également utiliser une expression régulière de vos caractères de liste blanche par rapport à la chaîne d'entrée. Vos événements sont disponibles sur MSDN ici: http://msdn.Microsoft.com/en-us/library/system.windows.forms.control.lostfocus.aspx

0
iivel