Permettre alphanumériques uniquement dans la zone de texte

j'ai une boîte de texte qui devrait interdire l'entrée de caractères spéciaux.

L'utilisateur peut entrer :

  1. A-Z
  2. a-z
  3. 0-9
  4. Espace

Comment puis-je faire le KeyDown événement pour ce faire?

16
demandé sur Sildoreth 2009-05-26 14:45:53

13 réponses

private void _txtPath_KeyDown(object sender, KeyEventArgs e)
  {
     if ((e.Key < Key.A) || (e.Key > Key.Z))
        e.Handled = true;
  }
2
répondu 2009-07-28 03:51:11

Gérer les évènements KeyDown ou KeyPress est une façon de le faire, mais les programmeurs oublient généralement qu'un utilisateur peut toujours copier-coller un texte non valide dans la zone de texte.

un moyen un peu plus efficace est de gérer L'événement TextChanged, et de supprimer tout personnage fautif. C'est un peu plus compliqué, car vous devez garder une trace de la position du caret et la remettre à l'endroit approprié après avoir changé la propriété Text de la boîte.

en Fonction de votre besoins de l'application, je laisserais juste l'utilisateur taper ce qu'il veut, et puis marquer la zone de texte (tourner le texte rouge ou quelque chose) quand l'utilisateur essaie de soumettre.

31
répondu MusiGenesis 2009-05-26 11:11:46

je voulais Juste rajouter un peu de code pour ceux se terminant jusqu'ici par la recherche de:

private void Filter_TextChanged(object sender, EventArgs e)
{
    var textboxSender = (TextBox)sender;
    var cursorPosition = textboxSender.SelectionStart;
    textboxSender.Text = Regex.Replace(textboxSender.Text, "[^0-9a-zA-Z ]", "");
    textboxSender.SelectionStart = cursorPosition;
}

ceci est un filtre de changement, donc gère la copie et le coller, et préserve la position du curseur pour que le changement de texte au milieu fonctionne correctement.

notez qu'il utilise le "sender" pour obtenir le nom de contrôle, permettant à cette fonction d'être liée à plusieurs boîtes de textbox, en supposant qu'ils ont besoin du même filtre. Vous pouvez lier plusieurs commandes en allant à la section d'événement d'une commande et manuellement choisir la fonction pour L'événement TextChanged.

12
répondu WhoIsRich 2014-03-13 15:35:29

Utilisez un regex pour filtrer les autres caractères. Ou utiliser des Char.Isdigit, méthodes IsXXX pour filtrer les caractères indésirables. Beaucoup de façons de le faire.

mise à jour: si vous devez utiliser KeyDown, il semble que vous ayez aussi besoin de gérer KeyPressed et set obEventArgs.Manipulés = true pour interdire les personnages. Voir l'exemple sur le KeyDown MSDN Page

mise à jour: maintenant que vous spécifiez que c'est WPF. Le code ci-dessous permet seulement les caractères A-z et A-Z d'être entré dans la zone de texte. Étendre si besoin...

private void _txtPath_KeyDown(object sender, KeyEventArgs e)
      {
         if ((e.Key < Key.A) || (e.Key > Key.Z))
            e.Handled = true;
      }

cela se cassera si vous copiez-collez des trucs dans la zone de texte. Valider le texte entier une fois que L'Utilisateur a quitté le contrôle ou quand il clique sur OK/Submit comme le dit MusicGenesis.

9
répondu Gishu 2009-05-26 11:12:40

je pense que cela vaut la peine d'envisager de faire le filtrage sur l'événement TextChanged de la boîte. Vous pouvez créer une opération qui se débarrasse de n'importe quels caractères non valides de votre chaîne de texte. C'est un peu plus compliqué que de bloquer L'évènement KeyDown.

mais, je pense que c'est la voie à suivre parce que vous ne bloquez pas les mécanismes de gestion des évènements de KeyDown/Up, donc copier/coller fonctionne toujours. Vous serait de travailler à un niveau plus élevé d'abstraction, donc je pense qu'il sera plus facile de comprendre ce qui se passe.

3
répondu Szymon Rozga 2009-05-26 13:15:43

je suis tombé sur ça à silverlight et j'ai écrit quelque chose comme ça.

private string _filterRegexPattern = "[^a-zA-Z0-9]"; // This would be "[^a-z0-9 ]" for this question.
private int _stringMaxLength = 24;


private void _inputTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    if (!string.IsNullOrEmpty(_filterRegexPattern))
    {
        var text = _inputTextBox.Text;
        var newText = Regex.Replace(_inputTextBox.Text, _filterRegexPattern, "");

        if (newText.Length > _stringMaxLength)
        {
            newText = newText.Substring(0, _stringMaxLength);
        }


        if (text.Length != newText.Length)
        {
            var selectionStart = _inputTextBox.SelectionStart - (text.Length - newText.Length);
            _inputTextBox.Text = newText;
            _inputTextBox.SelectionStart = selectionStart;
        }
    }
}
3
répondu shane 2013-01-30 21:44:28

j'accomplis ceci avec une propriété de dépendance personnalisée. Il est réutilisable pour tout TextBox contrôle, est beaucoup plus rapide et plus efficace à utiliser que la construction d'événements clés, et rend mes fichiers de code beaucoup plus propre.

en outre, il peut gérer d'autres méthodes d'entrée qui ne déclenchent pas d'événements clés, comme coller une valeur dans la zone de texte à l'aide de la souris.

le code pour le DP personnalisé ressemble à ceci:

// When set to a Regex, the TextBox will only accept characters that match the RegEx

/// <summary>
/// Lets you enter a RegexPattern of what characters are allowed as input in a TextBox
/// </summary>
public static readonly DependencyProperty AllowedCharactersRegexProperty =
    DependencyProperty.RegisterAttached("AllowedCharactersRegex",
                                        typeof(string), typeof(TextBoxProperties),
                                        new UIPropertyMetadata(null, AllowedCharactersRegexChanged));

// Get
public static string GetAllowedCharactersRegex(DependencyObject obj)
{
    return (string)obj.GetValue(AllowedCharactersRegexProperty);
}

// Set
public static void SetAllowedCharactersRegex(DependencyObject obj, string value)
{
    obj.SetValue(AllowedCharactersRegexProperty, value);
}

// Events
public static void AllowedCharactersRegexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var tb = obj as TextBox;
    if (tb != null)
    {
        if (e.NewValue != null)
        {
            tb.PreviewTextInput += Textbox_PreviewTextChanged;
            DataObject.AddPastingHandler(tb, TextBox_OnPaste);
        }
        else
        {
            tb.PreviewTextInput -= Textbox_PreviewTextChanged;
            DataObject.RemovePastingHandler(tb, TextBox_OnPaste);
        }
    }
}

public static void TextBox_OnPaste(object sender, DataObjectPastingEventArgs e)
{
    var tb = sender as TextBox;

    bool isText = e.SourceDataObject.GetDataPresent(DataFormats.Text, true);
    if (!isText) return;

    var newText = e.SourceDataObject.GetData(DataFormats.Text) as string;
    string re = GetAllowedCharactersRegex(tb);
    re = string.Format("[^{0}]", re);

    if (Regex.IsMatch(newText.Trim(), re, RegexOptions.IgnoreCase))
    {
        e.CancelCommand();
    }
}

public static void Textbox_PreviewTextChanged(object sender, TextCompositionEventArgs e)
{
    var tb = sender as TextBox;
    if (tb != null)
    {
        string re = GetAllowedCharactersRegex(tb);
        re = string.Format("[^{0}]", re);

        if (Regex.IsMatch(e.Text, re, RegexOptions.IgnoreCase))
        {
            e.Handled = true;
        }
    }
}

Et il est utilisé comme ceci:

<TextBox Text="{Binding SomeValue, UpdateSourceTrigger=PropertyChanged}" 
         local:TextBoxHelpers.AllowedCharactersRegex="a-zA-Z0-9\s" />
3
répondu Rachel 2014-03-13 16:11:18

je sais que les winForms ont un contrôle MaskedTextBox disponible, qui vous permet de spécifier exactement ce genre de chose. Je ne connais pas WPF, donc je ne sais pas si c'est disponible là-bas, mais si c'est le cas, faites-le. C'est beaucoup plus facile que tous ces trucs avec des touches et des événements, et plus robuste aussi.

2
répondu GWLlosa 2009-05-26 11:59:14

la façon la plus facile de faire cela serait d'inclure la boîte à outils WPF étendue qui a un contrôle pour faire exactement ce que vous demandez en spécifiant un masque.

http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox&referringTitle=Home

Il affiche également le masque dans la zone de texte que vous saisissez, si nécessaire.

(Il a également de nombreux autres contrôles)

2
répondu gr-eg 2011-10-14 15:22:50

et votre regExp pourrait ressembler à [0-9a-zA-Z]* pour autoriser uniquement l'anglais alphanumérique chracters

1
répondu Rune FS 2009-05-26 11:53:11

une seule zone de texte alphanumérique WPF, C#,

désolé pour mon anglais.. mais avec ce code pour WPF, c#, Je n'autorise qu'alphanumérique

private void txtTraslado_TextChanged(object sender, KeyEventArgs e)
{
  if (((e.Key < Key.NumPad0)||(e.Key > Key.NumPad9))&&((e.Key < Key.A)||(e.Key > Key.Z)))
  {
    e.Handled = true;
  }
}
1
répondu miguel 2011-12-07 17:24:05
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<asp:TextBox ID="txt_gpf_no" runat="server" CssClass="textbox" 
                                                MaxLength="10"></asp:TextBox>
<asp:FilteredTextBoxExtender ID="FilteredTextBoxExtender_gpf_no" runat="server" Enabled="True"
                                                TargetControlID="txt_gpf_no" FilterType="UppercaseLetters,LowercaseLetters,Custom" ValidChars="1234567890 ">
</asp:FilteredTextBoxExtender>
0
répondu Mr. P 2014-04-05 07:10:28

dans my.Net cadre 4.5 C # application

    private void txtRF_Register_Val_KeyDown(object sender, KeyEventArgs e)
    {
        //only enable alphanumeric
        if (!(((e.KeyCode < Keys.NumPad0) || (e.KeyCode > Keys.NumPad9)) && ((e.KeyCode < Keys.A) || (e.KeyCode > Keys.E))))
        {
            e.SuppressKeyPress = false;
        }
        else
        {
            e.SuppressKeyPress = true;
        }
    }
0
répondu Vincent Vrignaud 2015-06-24 13:22:43