2009-09-28 18 views
5

¿es posible usar la validación sin la parte Vinculante? La cuestión es que mi cuadro de texto no está vinculado a ningún objeto, pero aún quiero validar su contenido. La única forma que he encontrado hasta ahora es la siguiente:WPF Validar cuadro de texto no vinculado

<TextBox Grid.Row="0" Grid.Column="1" MaxLength="50" x:Name="textBoxTubeName" Margin="5,5,0,5"> 
     <TextBox.Text> 
      <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" NotifyOnValidationError="True"> 
       <Binding.ValidationRules> 
        <validation:InvalidCharactersRule /> 
       </Binding.ValidationRules> 
      </Binding> 
     </TextBox.Text> 
    </TextBox> 

Pero, de nuevo, sólo funciona cuando el TextBox.Text está obligado a algo (en este caso, la propiedad Name), ¿cómo iba a ir sobre esto sin enlace?

Gracias!

Respuesta

3

According to the MSDN forums aún no es posible pero está previsto (Nota: esta es una publicación anterior). Sin embargo, todavía no puedo encontrar la forma de hacerlo, por lo que es posible que aún no se haya implementado.

+0

Sí, creo que voy a tener que hacer el código yo mismo. Creo que la idea de Microsoft de concentrarse en el enlace es buena, pero limitar la validación de esta manera debido a ese propósito no es tan buena. Gracias Lucas. – Carlo

+0

@Carlo: Totalmente de acuerdo. – Kredns

+0

Hola. ¿Hay alguna actualización sobre este tema? Me gustaría hacer lo mismo. –

2

Es muy complicado hacerlo desde el código subyacente. Básicamente, puede establecer un enlace temporal desde el código y aumentar el error de validación, y cuando la entrada tenga un valor válido, puede eliminar todo el material de enlace temporal nuevamente.

Aquí lo que yo uso, que considero una mala práctica (pero es mejor de la nada):

/// <summary> 
    /// Marks a textBox control as invalid (via validation error) from code. 
    /// </summary> 
    /// <param name="textBox">The text box.</param> 
    /// <param name="errorContent">Content of the error.</param> 
    public static void ValidationMarkInvalid(TextBox textBox, String errorContent) 
    { 
     DependencyProperty textProp = TextBox.TextProperty; 
     if (!BindingOperations.IsDataBound(textBox, textProp)) 
     { 
      if (textBox.DataContext == null) 
      { 
       textBox.DataContext = new EmptyDataContext(); 
      } 

      Binding b = new Binding("CodeBehind"); 
      b.FallbackValue = textBox.Text; 
      b.ValidatesOnExceptions = true; 
      BindingOperations.SetBinding(textBox, textProp, b); 
     } 

     BindingExpression bindingInError = 
      textBox.GetBindingExpression(TextBox.TextProperty); 

     var validationError = new ValidationError(
      new EmptyValidationRule(), 
      bindingInError, 
      errorContent, 
      new Exception(errorContent)); 

     Validation.MarkInvalid(bindingInError, validationError); 
    } 

    /// <summary> 
    /// Clears the validation error from a textBox. 
    /// </summary> 
    /// <param name="textBox">The text box.</param> 
    public static void ValidationClear(TextBox textBox) 
    { 
     DependencyProperty textProp = TextBox.TextProperty; 
     if (BindingOperations.IsDataBound(textBox, textProp)) 
     { 
      String value = textBox.Text; 
      Validation.ClearInvalid(textBox.GetBindingExpression(TextBox.TextProperty)); 
      BindingOperations.ClearBinding(textBox, textProp); 
      textBox.Text = value; 

      EmptyDataContext ctx = textBox.DataContext as EmptyDataContext; 
      if (ctx != null) 
      { 
       textBox.DataContext = null; 
      } 
     } 
    } 

    #region Nested Type: EmptyDataContext 
    private sealed class EmptyDataContext : INotifyPropertyChanged 
    { 
     public Object CodeBehind 
     { 
      get 
      { 
       throw new FormatException(); 
      } 
      set 
      { 
       throw new FormatException(); 
      } 
     } 

     #region INotifyPropertyChanged Members 
     public event PropertyChangedEventHandler PropertyChanged; 
     #endregion 
    } 
    #endregion 

    #region Nested Type: EmptyValidationRule 
    private sealed class EmptyValidationRule : ValidationRule 
    { 
     /// <summary> 
     /// When overridden in a derived class, performs validation checks on a value. 
     /// </summary> 
     /// <param name="value">The value from the binding target to check.</param> 
     /// <param name="cultureInfo">The culture to use in this rule.</param> 
     /// <returns> 
     /// A <see cref="T:System.Windows.Controls.ValidationResult"/> object. 
     /// </returns> 
     public override ValidationResult Validate(Object value, CultureInfo cultureInfo) 
     { 
      return new ValidationResult(false, String.Empty); 
     } 
    } 
    #endregion 

Ahora, a partir de código subyacente que hace esto:

ValidationMarkInvalid(textBox, "Please enter something valid!"); 

ya despejar la validación:

ValidationClear(textBox); 

PD: Si no desea validar en las excepciones que puedas elimine la clase EmptyDataContext de los métodos anteriores.

Cuestiones relacionadas