Je voudrais créer une zone de texte qui accepte uniquement des valeurs numériques, dans une plage spécifique . Quel est le meilleur moyen d'implémenter une telle zone de texte?
J'ai pensé à dériver TextBox et à passer outre à la validation et à la contrainte de TextProperty. Cependant, je ne suis pas sûr de savoir comment procéder, et je comprends que dériver le contrôle de WPF n’est généralement pas recommandé .
private void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
int result;
if (!validateStringAsNumber(e.Text,out result,false))
{
e.Handled = true;
}
}
(validateStringAsNumber est ma fonction qui utilise principalement Int.TryParse)
Certaines des solutions suggérées sont probablement meilleures, mais pour la simple fonctionnalité dont j'avais besoin, cette solution est la plus simple et la plus rapide à mettre en œuvre, mais suffisante pour répondre à mes besoins.
La plupart des implémentations que j'ai vues jusqu'à présent utilisent l'événement PreviewTextInput pour implémenter le comportement de masque correct. Celui-ci hérite de TextBox et celui-ci utilise les propriétés attachées. Les deux utilisent. MaskedTextProvider de .Net pour fournir le comportement de masque correct, mais si vous voulez juste une simple zone de texte contenant uniquement des chiffres, vous n'avez pas besoin de cette classe.
private void txt_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
int iValue = -1;
if (Int32.TryParse(textBox.Text, out iValue) == false)
{
TextChange textChange = e.Changes.ElementAt<TextChange>(0);
int iAddedLength = textChange.AddedLength;
int iOffset = textChange.Offset;
textBox.Text = textBox.Text.Remove(iOffset, iAddedLength);
}
}
À mon humble avis, le meilleur moyen de satisfaire cette exigence consiste à utiliser uniquement l'événement OnTextChanged
, car il peut gérer le chiffre à partir d'une frappe au clavier et également être en mesure de gérer les fonctions Copier + Coller à partir du Presse-papiers. J'espère que mon code VB ci-dessous peut éclairer la situation.
Private Sub NumericBox_TextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged
Dim Buffer As New StringBuilder
Dim Index As Integer = Me.SelectionStart
For Each C In Me.Text
If Char.IsDigit(C) Then
Buffer.Append(C)
ElseIf Me.SelectionStart > Buffer.Length Then
Index -= 1
End If
Next
Me.Text = Buffer.ToString
Me.SelectionStart = Index
End Sub
Le mieux pour l’ensemble consiste à utiliser la méthode de substitution OnKeyPressed
pour la zone de texte, par exemple. Voici le code pour le remplacement utilisant la méthode statique Char IsDigit
.
if (!Char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar)) e.Handled = true;
C'est tout ce que vous devez vraiment faire.
Ce serait mon approche préférée:
private void yearTxt_PreviewKeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.D0:
case Key.D1:
case Key.D2:
case Key.D3:
case Key.D4:
case Key.D5:
case Key.D6:
case Key.D7:
case Key.D8:
case Key.D9:
case Key.NumLock:
case Key.NumPad0:
case Key.NumPad1:
case Key.NumPad2:
case Key.NumPad3:
case Key.NumPad4:
case Key.NumPad5:
case Key.NumPad6:
case Key.NumPad7:
case Key.NumPad8:
case Key.NumPad9:
case Key.Back:
break;
default:
e.Handled = true;
break;
}
}