2009-08-28 3 views
10

Je travaille actuellement sur une application WPF où j'aimerais avoir un TextBox qui ne peut contenir que des entrées numériques. Je sais que je peux valider le contenu quand j'ai perdu le focus et bloquer le contenu d'être numérique, mais dans d'autres applications Windows Form, nous bloquons totalement toute entrée sauf numérique d'être écrite. De plus, nous utilisons pour mettre ce code dans une DLL distincte pour le référencer dans de nombreux endroits.Validation dans la zone de texte dans WPF

Voici le code en 2008 n'utilisent pas WPF:

Public Shared Sub BloquerInt(ByRef e As System.Windows.Forms.KeyPressEventArgs, ByRef oTxt As Windows.Forms.TextBox, ByVal intlongueur As Integer) 
    Dim intLongueurSelect As Integer = oTxt.SelectionLength 
    Dim intPosCurseur As Integer = oTxt.SelectionStart 
    Dim strValeurTxtBox As String = oTxt.Text.Substring(0, intPosCurseur) & oTxt.Text.Substring(intPosCurseur + intLongueurSelect, oTxt.Text.Length - intPosCurseur - intLongueurSelect) 

    If IsNumeric(e.KeyChar) OrElse _ 
     Microsoft.VisualBasic.Asc(e.KeyChar) = System.Windows.Forms.Keys.Back Then 
     If Microsoft.VisualBasic.AscW(e.KeyChar) = System.Windows.Forms.Keys.Back Then 
      e.Handled = False 
     ElseIf strValeurTxtBox.Length < intlongueur Then 
      e.Handled = False 
     Else 
      e.Handled = True 

     End If 
    Else 
     e.Handled = True 
    End If 

est-il un moyen équivalent en WPF? Cela ne me dérangerait pas si c'est dans un style mais je suis nouveau à WPF donc le style est un peu obscur à ce qu'ils peuvent ou ne peuvent pas faire.

Répondre

23

Vous pouvez restreindre l'entrée aux nombres uniquement à l'aide d'une propriété jointe dans la zone de texte. Définissez la propriété jointe une fois (même dans une DLL séparée) et utilisez-la sur n'importe quel TextBox. Voici la propriété ci-joint:

using System; 
    using System.Windows; 
    using System.Windows.Controls; 
    using System.Windows.Input; 

    /// <summary> 
    /// Class that provides the TextBox attached property 
    /// </summary> 
    public static class TextBoxService 
    { 
     /// <summary> 
     /// TextBox Attached Dependency Property 
     /// </summary> 
     public static readonly DependencyProperty IsNumericOnlyProperty = DependencyProperty.RegisterAttached(
     "IsNumericOnly", 
     typeof(bool), 
     typeof(TextBoxService), 
     new UIPropertyMetadata(false, OnIsNumericOnlyChanged)); 

     /// <summary> 
     /// Gets the IsNumericOnly property. This dependency property indicates the text box only allows numeric or not. 
     /// </summary> 
     /// <param name="d"><see cref="DependencyObject"/> to get the property from</param> 
     /// <returns>The value of the StatusBarContent property</returns> 
     public static bool GetIsNumericOnly(DependencyObject d) 
     { 
     return (bool)d.GetValue(IsNumericOnlyProperty); 
     } 

     /// <summary> 
     /// Sets the IsNumericOnly property. This dependency property indicates the text box only allows numeric or not. 
     /// </summary> 
     /// <param name="d"><see cref="DependencyObject"/> to set the property on</param> 
     /// <param name="value">value of the property</param> 
     public static void SetIsNumericOnly(DependencyObject d, bool value) 
     { 
     d.SetValue(IsNumericOnlyProperty, value); 
     } 

     /// <summary> 
     /// Handles changes to the IsNumericOnly property. 
     /// </summary> 
     /// <param name="d"><see cref="DependencyObject"/> that fired the event</param> 
     /// <param name="e">A <see cref="DependencyPropertyChangedEventArgs"/> that contains the event data.</param> 
     private static void OnIsNumericOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
     bool isNumericOnly = (bool)e.NewValue; 

     TextBox textBox = (TextBox)d; 

     if (isNumericOnly) 
     { 
      textBox.PreviewTextInput += BlockNonDigitCharacters; 
      textBox.PreviewKeyDown += ReviewKeyDown; 
     } 
     else 
     { 
      textBox.PreviewTextInput -= BlockNonDigitCharacters; 
      textBox.PreviewKeyDown -= ReviewKeyDown; 
     } 
     } 

     /// <summary> 
     /// Disallows non-digit character. 
     /// </summary> 
     /// <param name="sender">The source of the event.</param> 
     /// <param name="e">An <see cref="TextCompositionEventArgs"/> that contains the event data.</param> 
     private static void BlockNonDigitCharacters(object sender, TextCompositionEventArgs e) 
     { 
     foreach (char ch in e.Text) 
     { 
      if (!Char.IsDigit(ch)) 
      { 
       e.Handled = true; 
      } 
     } 
     } 

     /// <summary> 
     /// Disallows a space key. 
     /// </summary> 
     /// <param name="sender">The source of the event.</param> 
     /// <param name="e">An <see cref="KeyEventArgs"/> that contains the event data.</param> 
     private static void ReviewKeyDown(object sender, KeyEventArgs e) 
     { 
     if (e.Key == Key.Space) 
     { 
      // Disallow the space key, which doesn't raise a PreviewTextInput event. 
      e.Handled = true; 
     } 
     } 
    } 

Voici comment l'utiliser (remplacer « contrôle » avec votre propre espace de noms):

<TextBox controls:TextBoxService.IsNumericOnly="True" /> 
+1

Je vais essayer ça. J'imagine que je peux pratiquement ajouter quelque chose comme ça. Par exemple, la longueur maximale du texte à l'intérieur, ce qui est aussi un autre problème que j'avais. –

+0

Oublié de mentionner, c'est la longueur maximale d'un nombre flottant (le nombre maximum de nombre décimal et maximum de la partie entière) –

+1

Oui, les propriétés attachées sont très puissantes et vous permettent d'ajouter tous les types de comportements. –

4

Vous pouvez mettre une validation dans votre fixation

<TextBox> 
     <TextBox.Text> 
       <Binding Path="CategoriaSeleccionada.ColorFondo" 
         UpdateSourceTrigger="PropertyChanged"> 
        <Binding.ValidationRules> 
          <utilities:RGBValidationRule /> 
        </Binding.ValidationRules> 
       </Binding> 
     </TextBox.Text> 
</TextBox> 

Regardez cet exemple (de mon programme), vous mettez la validation dans la liaison comme celui-ci. Avec UpdateSourceTrigger vous pouvez changer lorsque vous liaison sera mis à jour (mise au point perdu, dans tous les changements ...)

Eh bien, la validation est une classe, je vais vous mettre un exemple:

class RGBValidationRule : ValidationRule 
{ 
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) 
    { 
     // Here you make your validation using the value object. 
     // If you want to check if the object is only numbers you can 
     // Use some built-in method 
     string blah = value.ToString(); 
     int num; 
     bool isNum = int.TryParse(blah, out num); 

     if (isNum) return new ValidationResult(true, null); 
     else return new ValidationResult(false, "It's no a number"); 
    } 
} 

En bref , effectuez le travail à l'intérieur de cette méthode et renvoyez un nouveau ValidationResult. Le premier paramètre est un bool, true si la validation est bonne, false sinon. Le deuxième paramètre est seulement un message d'information. Je pense que c'est la base de la validation de textbox.

Espérons cette aide.

EDIT: Désolé, je ne connais pas VB.NET mais je pense que le code C# est assez simple.

+0

Je sais que les deux donc il est facile pour moi de Conver il. Merci, je vais essayer assez tôt. –

Questions connexes