2010-09-28 5 views
3

Nous avons plusieurs objets de données dans notre application qui s'enroulent liés aux grilles. Nous les avons implémentant l'interface IDataErrorInfo, de sorte qu'en ajoutant des messages d'erreur aux propriétés, nous voyons le style de changement rowheader et les DataGridCells gagner une bordure rouge. Tout va bien.Comportement de validation imitant sans validation

Nous avons maintenant une exigence supplémentaire que plutôt que de simplement avoir des erreurs, nous avons des erreurs et des avertissements. Les avertissements sont identiques aux erreurs sauf qu'ils devraient produire une bordure jaune au lieu d'une rouge.

Nous avons créé une nouvelle interface, IDataWarningInfo, basée sur IDataErrorInfo. Fonctionne bien. Je peux y accéder à l'exécution, j'ai RowValidatiionRules qui est capable d'y accéder, et de définir l'en-tête de ligne jaune au lieu du rouge, l'info-bulle appropriée, etc. Ce qui me manque, c'est la possibilité de définir la bordure d'une cellule en jaune, sur la base qu'il est databound à une propriété où cette propriété a un message d'avertissement.

Je pouvais récupérer ce message d'avertissement en transmettant le nom de la propriété databound à l'interface; Je soupçonne que sous le capot, le code de validation fait exactement cela. Ce qui me manque, c'est comment le faire en XAML. Plus précisément, je pense que je dois appliquer un style à une cellule, où ce style contient un DataTrigger qui transmet à l'objet le nom de la propriété DataBound, puis si le résultat est différent de null, applique quelques Setters à la cellule .

Est-ce que quelqu'un sait comment y parvenir?

Répondre

2

J'ai une classe avec une propriété attachée pour laquelle dependencyproperty à valider. Ensuite, il utilise DependencyPropertyDescriptor pour attacher un événement à l'événement de modification de ce dépendencyproperty.

Ensuite, lorsqu'il change, il parcourt les liaisons, exécute les règles de validation et définit les erreurs de validation de la propriété sans valider la liaison.

public static class ValidatingControlBehavior 
{ 
    /// <summary> 
    /// Defines the ValidatingProperty dependency property. 
    /// </summary> 
    public static readonly DependencyProperty ValidatingPropertyProperty = DependencyProperty.RegisterAttached("ValidatingProperty", typeof(DependencyProperty), typeof(ValidatingControlBehavior), 
     new PropertyMetadata(ValidatingControlBehavior.ValidatingPropertyProperty_PropertyChanged)); 

    /// <summary> 
    /// Attaches the event. 
    /// </summary> 
    /// <param name="control">The control.</param> 
    /// <param name="dependencyProperty">The dependency property.</param> 
    private static void AttachEvent(Control control, DependencyProperty dependencyProperty) 
    { 
     DependencyPropertyDescriptor.FromProperty(dependencyProperty, typeof(Control)).AddValueChanged(control, ValidatingControlBehavior.Control_PropertyChanged); 
     control.ForceValidation(dependencyProperty); 
    } 

    /// <summary> 
    /// Handles the PropertyChanged event of the Control control. 
    /// </summary> 
    /// <param name="sender">The source of the event.</param> 
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> 
    private static void Control_PropertyChanged(object sender, EventArgs e) 
    { 
     Control control = (Control)sender; 
     control.ForceValidation(ValidatingControlBehavior.GetValidatingProperty(control)); 
    } 

    /// <summary> 
    /// Forces the validation. 
    /// </summary> 
    /// <param name="dependencyObject">The dependency object.</param> 
    /// <param name="dependencyProperty">The dependency property.</param> 
    private static void ForceValidation(this DependencyObject dependencyObject, DependencyProperty dependencyProperty) 
    { 
     BindingExpressionBase expression = BindingOperations.GetBindingExpressionBase(dependencyObject, dependencyProperty); 
     Collection<ValidationRule> validationRules; 
     if (expression != null) 
     { 
      MultiBinding multiBinding; 
      Binding binding = expression.ParentBindingBase as Binding; 
      if (binding != null) 
      { 
       validationRules = binding.ValidationRules; 
      } 
      else if ((multiBinding = expression.ParentBindingBase as MultiBinding) != null) 
      { 
       validationRules = multiBinding.ValidationRules; 
      } 
      else 
      { 
       return; 
      } 
      for (int i = 0; i < validationRules.Count; i++) 
      { 
       ValidationRule rule = validationRules[i]; 
       ValidationResult result = rule.Validate(dependencyObject.GetValue(dependencyProperty), CultureInfo.CurrentCulture); 
       if (!result.IsValid) 
       { 
        Validation.MarkInvalid(expression, new ValidationError(rule, expression.ParentBindingBase, result.ErrorContent, null)); 
        return; 
       } 
      } 
      Validation.ClearInvalid(expression); 
     } 
    } 

    /// <summary> 
    /// Detaches the event. 
    /// </summary> 
    /// <param name="control">The control.</param> 
    /// <param name="dependencyProperty">The dependency property.</param> 
    private static void DetachEvent(Control control, DependencyProperty dependencyProperty) 
    { 
     DependencyPropertyDescriptor.FromProperty(dependencyProperty, typeof(Control)).RemoveValueChanged(control, ValidatingControlBehavior.Control_PropertyChanged); 
    } 

    /// <summary> 
    /// Handles the PropertyChanged event of the ValidatingPropertyProperty control. 
    /// </summary> 
    /// <param name="d">The source of the event.</param> 
    /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
    private static void ValidatingPropertyProperty_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     Control control = d as Control; 
     if (control != null) 
     { 
      if (e.OldValue != null) 
      { 
       ValidatingControlBehavior.DetachEvent(control, (DependencyProperty)e.OldValue); 
      } 
      if (e.NewValue != null) 
      { 
       ValidatingControlBehavior.AttachEvent(control, (DependencyProperty)e.NewValue); 
      } 
     } 
    } 

    /// <summary> 
    /// Gets the validating property. 
    /// </summary> 
    /// <param name="control">The control.</param> 
    /// <returns> 
    /// Dependency property. 
    /// </returns> 
    public static DependencyProperty GetValidatingProperty(Control control) 
    { 
     return (DependencyProperty)control.GetValue(ValidatingControlBehavior.ValidatingPropertyProperty); 
    } 

    /// <summary> 
    /// Sets the validating property. 
    /// </summary> 
    /// <param name="control">The control.</param> 
    /// <param name="validatingProperty">The validating property.</param> 
    public static void SetValidatingProperty(Control control, DependencyProperty validatingProperty) 
    { 
     control.SetValue(ValidatingControlBehavior.ValidatingPropertyProperty, validatingProperty); 
    } 
} 
Questions connexes