views:

30

answers:

1

I have a form:

<StackPanel x:Name="LayoutRoot">
    <sdk:ValidationSummary />

    <sdk:Label Target="{Binding ElementName=Greeting}" />
    <TextBox x:Name="Greeting" Text="{Binding Greeting, Mode=TwoWay,
        ValidatesOnExceptions=True, NotifyOnValidationError=True}" />

    <sdk:Label Target="{Binding ElementName=Name}" />
    <TextBox x:Name="Name" Text="{Binding Name, Mode=TwoWay,
        ValidatesOnExceptions=True, NotifyOnValidationError=True}" />
</StackPanel>

And a simple class this is set as the DataContext...

  public class Person : INotifyPropertyChanged
    {
        private string _greeting;

        private string _name;

        public string Greeting
        {
            get { return _greeting; }
            set
            {
                _greeting = value;
                InvokePropertyChanged(new PropertyChangedEventArgs("Greeting"));
            }
        }

        [Required(ErrorMessage = "Name must be provided")]
        [StringLength(15, MinimumLength = 5,
            ErrorMessage = "Name should be 5 to 15 characters")]
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                InvokePropertyChanged(new PropertyChangedEventArgs("Name"));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void InvokePropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, e);
        }
    }

I set the data context with the following line in the code behind of the xaml:

    DataContext = new Person {Name = "Joe User"};

I see the data on the form, and the label for Name is bold, indicating required. However, if I empty the field, or set it to a string of an invalid length, I get no validation, on the label itself, or the validation summary. I understand the textbox doesn't validate until lost focus, so I click into the greeting field and enter text to make sure I've left the other text control.

What am I missing here?

Answer:

Per @Alex Paven's answer, to get it to work with Data Annotations you would use:

[Required(ErrorMessage = "Name must be provided")]
[StringLength(15, MinimumLength = 5,
    ErrorMessage = "Name should be 5 to 15 characters")]
public string Name
{
    get { return _name; }
    set
    {
        Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = "Name" });
        _name = value;
        InvokePropertyChanged(new PropertyChangedEventArgs("DisplayName"));
    }
}

As for IDataErrorInfo, I'll look into it. Thanks!

+2  A: 

You're missing the actual validation call. With ValidatesOnExceptions, an exception must be thrown in the property setter, and the attributes are not taken into account automatically with respect to validation. For it to work you need a call to System.ComponentModel.DataAnnotations.Validator.ValidateProperty with the correct parameters.

However, if using Silverlight 4, I'd suggest looking into validating with IDataErrorInfo, as I feel it offers a lot more flexibility.

Alex Paven
I agree. IDataErrorInfo is a much better way to go. On my current project I have a base class for my ViewModels that implements IDataErrorInfo and calls separate validation classes that use the FluentValidation library.
Matt Casto