2010-01-15 8 views
2

J'essaie de trouver une manière élégante de valider deux valeurs TextBox liées dans WPF.Validation de plusieurs valeurs TextBox de la base de données liée dans WPF

La propriété Text de chaque zone de texte est lié à une propriété publique décimale sur ma classe qui implémente INotifyPropertyChanged pour TwoWay obligatoire.

Je veux valider les deux valeurs telles que: BiggerValue> = SmallerValue> = 0

J'ai réussi à obtenir chaque valeur pour valider de façon indépendante par rapport à ces conditions d'utilisation IDataErrorInfo et un indexeur de chaîne.

Mon problème est le suivant: l'utilisateur a l'intention de réduire les valeurs et commence par BiggerValue, de sorte qu'il est maintenant inférieur à SmallerValue. La validation sur le TextBox BiggerValue échoue (bien que la valeur soit stockée). L'utilisateur passe ensuite à SmallerValue et le définit moins que le nouveau BiggerValue. Maintenant, les deux valeurs sont à nouveau valides, mais comment puis-je obtenir la zone de texte BiggerValue pour refléter automatiquement que sa valeur (inchangé) est maintenant valide?

Dois-je être à la recherche à un gestionnaire d'événements comme LostFocus() sur les zones de texte ou d'ajouter quelque chose comme ceci aux poseurs de propriété pour forcer un rafraîchissement?

biggerValueTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 
smallerValueTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 

Mon code complet est ci-dessous. D'une certaine manière tout se sent plutôt maladroit et trop compliqué pour ce problème simple. En tant que débutant WPF (c'est le jour 2), tous les commentaires sur mon approche, aussi radical soit-il, seraient les bienvenus.

XAML:

<TextBox x:Name="biggerValueTextBox" 
     Text="{Binding Path=BiggerValue, 
         Mode=TwoWay, 
         ValidatesOnDataErrors=True, 
         ValidatesOnExceptions=True}" /> 
<TextBox x:Name="smallerValueTextBox" 
     Text="{Binding Path=SmallerValue, 
         Mode=TwoWay, 
         ValidatesOnDataErrors=True, 
         ValidatesOnExceptions=True}" /> 

C#:

public partial class MyClass : UserControl, 
    INotifyPropertyChanged, IDataErrorInfo 
{ 
    // properties 
    private decimal biggerValue = 100; 
    public decimal BiggerValue 
    { 
     get 
     { 
      return biggerValue; 
     } 
     set 
     { 
      biggerValue = value; 
      OnPropertyChanged("BiggerValue"); 
     } 
    } 
    private decimal smallerValue = 80; 
    public decimal SmallerValue 
    { 
     get 
     { 
      return smallerValue; 
     } 
     set 
     { 
      smallerValue = value; 
      OnPropertyChanged("SmallerValue"); 
     } 
    } 

    // error handling 
    public string this[string propertyName] 
    { 
     get 
     { 
      if (propertyName == "BiggerValue") 
      { 
       if (BiggerValue < SmallerValue) 
        return "BiggerValue is less than SmallerValue."; 
       if (BiggerValue < 0) 
        return "BiggerValue is less than zero."; 
      } 
      if (propertyName == "SmallerValue") 
      { 
       if (BiggerValue < SmallerValue) 
        return "BiggerValue is less than SmallerValue."; 
       if (SmallerValue < 0) 
        return "SmallerValue is less than zero."; 
      } 
      return null; 
     } 
    } 
    // WPF doesn't use this property. 
    public string Error { get { return null; } } 

    // event handler for data binding 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
+1

Possible copie de [Règles de validation utilisant la valeur d'un autre contrôle] (http://stackoverflow.com/questions/18554019/validation-rules-using-value-from- un autre contrôle) – Dzyann

Répondre

1

bien, une méthode hackish facile serait de tirer propriété a changé pour le biggerValue ainsi (ce qui provoquera une actualisation de la validation de la plus grande valeur):

public decimal SmallerValue 
    { 
     get 
     { 
      return smallerValue; 
     } 
     set 
     { 
      bool fireForBigger = smallerValue > biggerValue && smallerValue < value; 
      smallerValue = value; 
      OnPropertyChanged("SmallerValue"); 
      if (fireForBigger) 
      { 
       OnPropertyChanged("BiggerValue"); 
      } 
     } 
    } 

Mais, une solution plus solide serait de créer une règle de validation personnalisée s et réglez le tout sur votre propre: http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validationrules.aspx

+0

Merci pour cela et pour avoir répondu si rapidement - c'est une solution agréable et simple. Je regarderai les règles de validation personnalisées aussi. –

+0

En quoi l'utilisation de règles de validation personnalisées serait-elle utile? On dirait que ce serait le même problème qu'avec IDataErrorInfo. – HappyNomad