2011-01-14 5 views
6

Ich habe eine einfache Testseite in meiner Silverlight 4-Anwendung, in der ich versuche, eine benutzerdefinierte Validierungsregel zu feuern.CustomValidation-Attribut scheint nicht zu funktionieren

Ich habe eine TextBox und eine Schaltfläche, und ich zeige die Validierungsergebnisse in einem TextBlock. Mein Ansichtsmodell verfügt über eine Name-Eigenschaft, die an die Text-Eigenschaft der TextBox gebunden ist. Ich habe zwei Validierungsattribute für die Name-Eigenschaft [Required] und [CustomValidation].

Wenn ich den Submit-Button drücke, wird der Required Validator korrekt ausgelöst, aber der Haltepunkt innerhalb der Validierungsmethode meines benutzerdefinierten Validators wird nie getroffen. Ich kann nicht sehen, warum dies ist, wie ich glaube, ich habe MS das Beispiel sehr aufmerksam verfolgt: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.customvalidationattribute(v=vs.95).aspx

Hier ist der Code für die Ansicht Modell ist:

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 
using GalaSoft.MvvmLight.Command; 

namespace MyProject 
{ 
    // custom validation class 
    public class StartsCapitalValidator 
    { 
     public static ValidationResult IsValid(string value) 
     { 
      // this code never gets hit 
      if (value.Length > 0) 
      { 
       var valid = (value[0].ToString() == value[0].ToString().ToUpper()); 
       if (!valid) 
        return new ValidationResult("Name must start with capital letter"); 
      } 
      return ValidationResult.Success; 
     } 
    } 

    // my view model 
    public class ValidationTestViewModel : ViewModelBase 
    { 
     // the property to be validated 
     string _name; 
     [Required] 
     [CustomValidation(typeof(StartsCapitalValidator), "IsValid")] 
     public string Name 
     { 
      get { return _name; } 
      set { SetProperty(ref _name, value,() => Name); } 
     } 

     string _result; 
     public string Result 
     { 
      get { return _result; } 
      private set { SetProperty(ref _result, value,() => Result); } 
     } 

     public RelayCommand SubmitCommand { get; private set; } 

     public ValidationTestViewModel() 
     { 
      SubmitCommand = new RelayCommand(Submit); 
     } 

     void Submit() 
     { 
      // perform validation when the user clicks the Submit button 
      var errors = new List<ValidationResult>(); 
      if (!Validator.TryValidateObject(this, new ValidationContext(this, null, null), errors)) 
      { 
       // we only ever get here from the Required validation, never from the CustomValidator 
       Result = String.Format("{0} error(s):\n{1}", 
        errors.Count, 
        String.Join("\n", errors.Select(e => e.ErrorMessage))); 
      } 
      else 
      { 
       Result = "Valid"; 
      } 
     } 
    } 
} 

Hier ist die Ansicht:

<navigation:Page x:Class="Data.Byldr.Application.Views.ValidationTest" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"> 
    <Grid Width="400"> 
    <StackPanel> 
     <TextBox Text="{Binding Name, Mode=TwoWay}" /> 
     <Button Command="{Binding SubmitCommand}" Content="Submit" /> 
     <TextBlock Text="{Binding Result}" /> 
    </StackPanel> 
    </Grid> 
</navigation:Page> 
+0

Orthogonal zu der eigentlichen Frage, aber FWIW können Sie die Überprüfung über die statische Methode Char.IsUpper: http://msdn.microsoft.com/en-us/library/system.char.isupper(v=VS.100)) .aspx –

Antwort

11

Wie auf der MSDN-Seite für diese Überladung von Validator.TryValidateObject (http://msdn.microsoft.com/en-us/library/dd411803(v=VS.95).aspx) angegeben, werden nur die Prüfungen auf Objektebene mit dieser Methode und RequiredAttribute auf Eigenschaften überprüft.

Immobilien-Ebene Validierungen Um zu überprüfen, verwenden Sie die Überlastung, die also auch ein Bool (http://msdn.microsoft.com/en-us/library/dd411772(v=VS.95).aspx)

es sollte so einfach wie nebenbei "true" als zusätzliche Parameter zu TryValidateObject

+0

Es hat funktioniert! Vielen Dank. –

+0

Was genau hast du in den Code geschrieben, damit es für dich funktioniert? –

+0

was sollte ich noch tun von http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.customvalidationattribute(v=vs.95).aspx? –

11

Warum don‘nimmt t Sie Ihre eigene Validierung erstellen dieses Attribut wie ..

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 

public class StartsCapital : ValidationAttribute 
{ 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      var text = value as string; 

      if(text == null) 
       return ValidationResult.Success; 

      if (text.Length > 0) 
      { 
       var valid = (text[0].ToString() == text[0].ToString().ToUpper()); 
       if (!valid) 
        return new ValidationResult("Name must start with capital letter"); 
      } 
      return ValidationResult.Success; 
     } 
} 

und dann verwenden, wie

// my view model 
public class ValidationTestViewModel : ViewModelBase 
{ 
    // the property to be validated 
    string _name; 
    [Required] 
    [StartsCapital] 
    public string Name 
    { 
     get { return _name; } 
     set { SetProperty(ref _name, value,() => Name); } 
    } 
+1

Ich bevorzuge das Attribut [CustomValidation]. –