C# – How to add a close button to ValidationSummary in Silverlight

csilverlight

In Silverlight 3 I am working with a MVVM and also the validation principle that the setters cause an exception if a validation error occurs. I using the Binding Syntax on the fields using TwoWay i.e.:

<TextBox x:Name="TextBoxClientName" Text="{Binding Name,Mode=TwoWay,ValidatesOnExceptions=True,NotifyOnValidationError=true}"  Grid.Column="1" Grid.Row="0" Margin="5 5 5 5" />

I validate this property in the ViewModel using the Annotations:

[Required(ErrorMessage = "Name is required")]
public string Name
{
    get
    {
        return _client.Name;
    }
    set
    {
        Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = "Name", DisplayName="Client Name" });
        _client.Name = value;
    }
}

I have the Validation summary and all work well BUT lol, the functionality I am looking for is the following:

You have the Data Form and I want the validation summary to appear over the top ONLY when I click save, and further more I want to implement a close button on that ValidationSummary so the user can continue on with entering and correcting.

I am not sure how to control the visibility or toggle of with the validationsummary, I have tried the Visibility. The following is code that I tried, WHICH does collect the errors on submit, but I cannot apply them to the validationsummary:

    public void Save()
    {
        List<ValidationError> errors = new List<ValidationError>();

        foreach (UIElement ui in LayoutRoot.Children)
        {
            FrameworkElement fe = ui as FrameworkElement;

            if (fe != null)
            {
                foreach (ValidationError ve in Validation.GetErrors(fe))
                {
                    errors.Add(ve);
                }
            }
        }


        if (errors.Count > 0)
        {

            Validation1.DataContext = errors;
            Validation1.Filter = ValidationSummaryFilters.All;
        }
        else
        {
            if (Saved != null)
                Saved(this, EventArgs.Empty);
        }

    }

Cheers,

Andrew

Best Answer

I guess that by now you're using SIlverlight 4 in your apps. So this answer is for Silverlight 4.

With Silverlight 4 a new interface was added INotifyDataError with 3 methods:

public interface INotifyDataErrorInfo 
{
    // Returns True if the object has at least one property-level or top-level error. 
    bool HasErrors { get; }

    // Returns the current set of property-level errors for the provided property name, or
    // the current top-level errors if the argument is null or empty. 
    IEnumerable GetErrors(string propertyName);

    // Raised when the set of errors for a particular property has changed, or when the 
    // top-level errors have changed. 
    event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
}

There is vast documentation around the web about that interface and how to use it.

You don't have to use DataAnotations if you don't want to. But if you do, you still will be able to get the validation errors using the Validator class from the System.ComponentModel.DataAnnotations namespace.

If you make your ViewModel implement INotifyDataError and have also a property (in the ViewModel) bool IsValidating or something like that. Then every time the property changes fire the ErrorsChanged event for all the properties that you want to validate (you could get the property names using reflection). And thats it.

Now you just have to make IsValidating = false and then when Save is requested show the errors with IsValidating = true.

Other thing that you could do (and this would work on Silverlight 3) is bind the Visibility of the ValidationSummary to the IsValidating property (using a IValueConverter), and then control this from the ViewModel.