2009-08-28 15 views
10

Actualmente estoy trabajando en una aplicación WPF donde me gustaría tener un TextBox que solo puede tener entradas numéricas. Sé que puedo validar el contenido cuando pierdo el foco y bloquear el contenido para que no sea numérico, pero en otra aplicación de Windows Form, utilizamos para bloquear por completo cualquier entrada, excepto la numérica, de que se anote. Además, usamos para poner ese código en un dll separado para referenciarlo en muchos lugares.Validación en el cuadro de texto en WPF

Aquí está el código en 2008 no usar 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 

¿Hay una manera equivalente en WPF? No me importaría si esto tiene un estilo, pero soy nuevo en WPF, por lo que el estilo es un poco oscuro para lo que pueden o no pueden hacer.

Respuesta

23

Puede restringir la entrada a números solo usando una propiedad adjunta en el TextBox. Defina la propiedad adjunta una vez (incluso en un dll separado) y úselo en cualquier TextBox. Aquí está el bien embargado:

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; 
     } 
     } 
    } 

aquí es cómo usarlo (en lugar de "controles" con su propio espacio de nombres):

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

Lo intentaré. Imagino que prácticamente puedo agregar algo así. Por ejemplo, la longitud máxima del texto dentro, que también es otro problema que tuve. –

+0

Ha olvidado mencionar que es la longitud máxima de un número flotante (el número máximo de número decimal y máximo de la parte entera) –

+1

Sí, las propiedades adjuntas son muy potentes y le permitieron agregar todo tipo de comportamientos. –

4

Se puede poner una validación en su unión

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

vistazo a este ejemplo (de mi programa), se pone la validación dentro de la unión como esta. Con UpdateSourceTrigger puede cambiar cuando la unión se actualizará (enfoque perdido, en cada cambio ...)

Bueno, la validación es una clase, voy a poner un ejemplo:

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 pocas palabras , haz el trabajo dentro de ese método y devuelve un nuevo ValidationResult. El primer parámetro es un bool, verdadero si la validación es buena, falso si no. El segundo parámetro es solo un mensaje de información.

Creo que esto es lo básico de la validación del cuadro de texto.

Espero que esta ayuda.

EDITAR: Lo siento, no sé VB.NET, pero creo que el código C# es bastante simple.

+0

que sé tanto por lo que es fácil para mí ConVer ella. Gracias, lo intentaré lo suficientemente pronto. –

Cuestiones relacionadas