web-dev-qa-db-fra.com

Autoriser uniquement la saisie numérique dans la zone de texte WPF

J'aimerai valider l'entrée d'utilisateur pour m'assurer que ce sont des entiers. Comment puis-je le faire? J'ai pensé à utiliser IDataErrorInfo qui semble être la "bonne" méthode de validation dans WPF. J'ai donc essayé de l'implémenter, dans mon ViewModel.

Mais la chose est que ma zone de texte est liée à un champ entier, et il n'est pas nécessaire de valider si une int est une int. J'ai remarqué que WPF ajoute automatiquement une bordure rouge autour de la zone de texte pour informer l'utilisateur de l'erreur. La propriété sous-jacente ne change pas en une valeur invalide. Mais je voudrais informer l'utilisateur de cela. Comment puis-je le faire?

12
Jiew Meng

La bordure rouge que vous avez vue est en réalité un ValidationTemplate, que vous pouvez étendre et ajouter une information à l'utilisateur. Voir cet exemple:

    <UserControl.Resources>
        <ControlTemplate x:Key="validationTemplate">
            <Grid>
                <Label Foreground="Red" HorizontalAlignment="Right" VerticalAlignment="Center">Please insert a integer</Label>
                <Border BorderThickness="1" BorderBrush="Red">
                    <AdornedElementPlaceholder />
                </Border>
            </Grid>
        </ControlTemplate>
    </UserControl.Resources>

<TextBox Name="tbValue" Validation.ErrorTemplate="{StaticResource validationTemplate}">
11
Andrei Pana

Une autre façon consiste simplement à ne pas autoriser les valeurs qui ne sont pas des entiers. L’implémentation suivante est un peu fastidieuse, et je voudrais l’abréger plus tard pour qu’elle soit plus réutilisable, mais voici ce que j’ai fait:

dans le code derrière à mon avis (je sais que cela pourrait faire mal si vous êtes un mvvm hardcore; o)), j'ai défini les fonctions suivantes:

  private void NumericOnly(System.Object sender, System.Windows.Input.TextCompositionEventArgs e)
{
    e.Handled = IsTextNumeric(e.Text);

}


private static bool IsTextNumeric(string str)
{
    System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("[^0-9]");
    return reg.IsMatch(str);

}

Et dans la vue XAML, chaque zone de texte supposée accepter uniquement des entiers était définie comme suit:

   <TextBox Padding="2"  TextAlignment="Right" PreviewTextInput="NumericOnly" Text="{Binding xxx.yyyy}" MaxLength="1" />

L'attribut clé étant PreviewTextInput

14

Nous pouvons effectuer une validation sur l'événement de zone de texte modifié. L’implémentation suivante évite d’appuyer sur une touche autre que numérique et un point décimal.

private void textBoxNumeric_TextChanged(object sender, TextChangedEventArgs e)
{
        TextBox textBox = sender as TextBox;
        Int32 selectionStart = textBox.SelectionStart;
        Int32 selectionLength = textBox.SelectionLength;
        String newText = String.Empty;
        int count = 0;
        foreach (Char c in textBox.Text.ToCharArray())
        {
            if (Char.IsDigit(c) || Char.IsControl(c) || (c == '.' && count == 0))
            {
                newText += c;
                if (c == '.')
                    count += 1;
            }
        }
        textBox.Text = newText;
        textBox.SelectionStart = selectionStart <= textBox.Text.Length ? selectionStart : textBox.Text.Length;    
}
8
kumar Gouraw

si vous travaillez dans WPF Mieux vaut utiliser l'événement PreviewTextInput qui prend en charge toutes les plateformes et à partir de presentationcore.dll

voici l'exemple:

private void TextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
    {
        if ((e.Text) == null || !(e.Text).All(char.IsDigit))
        {
            e.Handled = true;
        }
    }
0
Gaurav Panwar