2009-09-28 1 views
5

Можно ли использовать валидацию без привязки? Дело в том, что мое текстовое поле не привязано к какому-либо объекту, но я все еще хочу проверить его содержимое. Единственный способ, которым я нашел до сих пор это:WPF Подтверждение несвязанного текстового поля

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

Но опять же, это работает только тогда, когда TextBox.Text связан с чем-то (в данном случае, свойство Name), как бы я идти об этом без привязки?

Спасибо!

ответ

3

According to the MSDN forums еще не планируется, но планируется (Примечание: это старое сообщение). Тем не менее, я до сих пор не могу найти способ сделать это, чтобы он еще не был реализован.

+0

Да, я думаю, что мне нужно будет сделать код сам. Я думаю, что идея Microsoft сосредоточиться на привязке хороша, но ограничение этой проверки в этом случае не так хорошо. Спасибо, Лукас. – Carlo

+0

@ Карло: Полностью согласовано. – Kredns

+0

Привет. Есть ли какие-либо обновления по этому вопросу? Я хотел бы сделать то же самое. –

2

Очень сложно сделать из кода. В принципе, вы можете установить временную привязку из кода и поднять ошибку проверки, и когда вход имеет действительное значение, вы можете снова удалить все временные привязки.

Вот что я использую, которые я считаю плохой практикой (но это лучше из ничего):

/// <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 

Теперь из кода фоновым вы это делаете:

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

и очистить проверки:

ValidationClear(textBox); 

PS: Если вы не хотите, чтобы проверить на исключениях вы можете удалите класс EmptyDataContext из указанных выше методов.