2010-11-25 8 views
16

XAML:Accès des règles de validation de commande WPF à partir du code

 
    <TextBox Name="textboxMin"> 
     <TextBox.Text> 
      <Binding Path="Max"> 
       <Binding.ValidationRules> 
        <local:IntValidator/> 
       </Binding.ValidationRules> 
      </Binding> 
     </TextBox.Text> 
    </TextBox> 

code:

 
void buttonOK_Click(object sender, RoutedEventArgs e) 
{ 
    // I need to know here whether textboxMin validation is OK 
    // textboxMin. ??? 

    // I need to write something like: 
    // if (textboxMin.Validation.HasErrors) 
    //  return; 
} 

Ce serait bien aussi de savoir, comment désactiver le bouton OK, si au moins l'un des contrôles de dialogue doesn pas passer la validation - en XAML, en utilisant la liaison. De cette façon, je n'ai pas besoin de vérifier l'état de validation dans le code.

+0

Est-ce que vous devez savoir si une erreur a ValidationRule spécifique ou tout simplement si la zone de texte contient des erreurs? –

Répondre

22

Validation.HasError est une propriété attachée de sorte que vous pouvez vérifier pour textboxMin comme celui-ci

void buttonOK_Click(object sender, RoutedEventArgs e) 
{ 
    if (Validation.GetHasError(textboxMin) == true) 
     return; 
} 

Pour exécuter tous ValidationRules pour le TextProperty dans le code derrière vous pouvez obtenir le BindingExpression et appelez UpdateSource

BindingExpression be = textboxMin.GetBindingExpression(TextBox.TextProperty); 
be.UpdateSource(); 

Mise à jour

Il prendra des mesures pour réaliser la liaison à disab le bouton si une validation a lieu. Tout d'abord, assurez-vous que toutes les liaisons ajoutent NotifyOnValidationError = "True". Exemple

<TextBox Name="textboxMin"> 
    <TextBox.Text> 
     <Binding Path="Max" NotifyOnValidationError="True"> 
      <Binding.ValidationRules> 
       <local:IntValidator/> 
      </Binding.ValidationRules> 
     </Binding> 
    </TextBox.Text> 
</TextBox> 

Ensuite, nous brancher un gestionnaire d'événements à l'événement Validation.Error dans la fenêtre.

<Window ... 
     Validation.Error="Window_Error"> 

Et dans le code derrière nous ajoutons et supprimons les erreurs de validation dans un ObservableCollection comme ils viennent et aller

public ObservableCollection<ValidationError> ValidationErrors { get; private set; } 
private void Window_Error(object sender, ValidationErrorEventArgs e) 
{ 
    if (e.Action == ValidationErrorEventAction.Added) 
    { 
     ValidationErrors.Add(e.Error); 
    } 
    else 
    { 
     ValidationErrors.Remove(e.Error); 
    } 
} 

Et nous pouvons lier IsEnabled du bouton à ValidationErrors.Count comme celui-ci

<Button ...> 
    <Button.Style> 
     <Style TargetType="Button"> 
      <Setter Property="IsEnabled" Value="False"/> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding ValidationErrors.Count}" Value="0"> 
        <Setter Property="IsEnabled" Value="True"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Button.Style> 
</Button> 
+0

Première version - Validation.HasError n'est pas compilé. Après l'édition, GetHasError est OK et donne le résultat attendu. Merci. –

+0

Bien mieux d'utiliser AttachedProperty ou Behavior à cette fin, mais merci de mentionner NotifyOnValidationError doit être défini sur true! –

6

vous devez obtenir la liaison avant de vous les règles

Binding b= BindingOperations.GetBinding(textboxMin,TextBox.TextProperty); 
    b.ValidationRules 

que vous pouvez avoir BindingExpression et vérifier propriété HasError

BindingExpression be1 = BindingOperations.GetBindingExpression (textboxMin,TextBox.TextProperty); 

be1.HasError 
+1

BindingOperations.GetBindingExpression (textBoxMin, TextBox.TextProperty) .HasError a fait l'affaire. –

+0

Enfin j'utilise la version courte Validation.GetHasError (textboxMin). Merci. –

+0

que devrais-je mettre en tant que propriété si je veux vérifier les liaisons de DataGrid? par exemple. BindingOperations.GetBindingExpression (myDatagrid,?). HasError – DasDas