Remove ValidationRule

Dec 19, 2012 at 6:03 PM

Hi!

First of all thanks that this helper is available for everybody. Very cool tool!

But I (maybe others as well) need one more funcitionality.

I need to remove some ValidationRule from the ValidationHelper. Because some application need to have different ValidationRules in different status.

I've tried to create a new instance of ValidationHelper and NotifyDataErrorInfoAdapter and it deletes all ValidationRules of course, but after the new instance creation, controls of View don't show their Validation errors.

So it would be very useful functionality to remove ValidationRules from ValidationHelper without create a new instance.

Coordinator
Dec 25, 2012 at 1:16 PM
Edited Dec 26, 2012 at 1:11 PM

Hi!

Thanks for your feedback!

Indeed, I think the possibility to remove a rule could be useful, so I added it. You can grab a build here: http://mvvmvalidation.codeplex.com/downloads/get/582321.

Now, the AddRule methods return an instance of IValidationRule, and the RemoveRule method, which I added, accepts an instance of IValidationRule that you would like to remove. Please note that after you've removed a rule, you need to re-execute the validation in order to update the validation results by calling one of the Validate methods.

Please give it a try and let me know what you think!

Dec 26, 2012 at 10:51 AM

Hi!

Thank you for your quick answer.

I have tried the RemoveRule method and it works fine. Thank you!

Is it possible to you create a method which remove all ValidationRule? It would be more useful for me, because I don't need to have keep referneces of ValidationRules and I use RequiredRule a lot and it doesn' have return value.

Coordinator
Dec 26, 2012 at 1:10 PM

I've added the RemoveAllRules method that removes all rules. As well as I've changed the AddRequiredRule method to return an instance of IValidationRule just like other AddRule methods.

You can get a build here: http://mvvmvalidation.codeplex.com/downloads/get/582468

Please let me know if it is enough for your needs.

Dec 28, 2012 at 9:23 AM

I've tried the new method and it works perfect. It's absolutly enough for me.

Thanks again your help and quick reaction. :)

Jan 2, 2013 at 9:59 AM

Hi,

I've found a strange behavior during the validation.

After remove validation rules from Validator, the UI is not updating its validation state. (TextBoxes and other contorls show validation errors)

In debugging mode I saw that the count of ValidationRules is 0, but the ruleValidationResultMap is still same as it was before, and the count of properties (which have validation rule) in ruleValidationResultMap are increasing countinuisly after I use ValidateAll() method.

Jan 1, 2014 at 6:48 PM
joesimon wrote:
Hi, I've found a strange behavior during the validation. After remove validation rules from Validator, the UI is not updating its validation state. (TextBoxes and other contorls show validation errors) In debugging mode I saw that the count of ValidationRules is 0, but the ruleValidationResultMap is still same as it was before, and the count of properties (which have validation rule) in ruleValidationResultMap are increasing countinuisly after I use ValidateAll() method.
Hi I too faced the same issue, when removing a rule from Validator.
Jan 1, 2014 at 9:57 PM
Hi,

Thanks for such an amazing framework.

I have found an solution for the above issue. I have added a method which will remove the ValidationRule from ruleValidationResultMap during the next valition.

Please add this in ValidationHelper.cs
private void RemoveUnregisteredValidationRuleFromMap(object target ,IEnumerable<ValidationRule> rules)
{
    lock ( syncRoot )
    {
        if ( ruleValidationResultMap.ContainsKey(target) )
        {
            var validationRulesToRemove = ruleValidationResultMap[target].Keys.Except(rules).ToList();
            foreach ( var validationRule in validationRulesToRemove )
                ruleValidationResultMap.Single(x => x.Key == target).Value.Remove(validationRule);
        }
    }
}
This will be called by ValidateInternal(object target) just after var rulesToExecute = GetRulesForTarget(target);
[SuppressMessage("Microsoft.Naming" ,"CA2204:Literals should be spelled correctly" ,MessageId = "ValidateAsync")]
private ValidationResult ValidateInternal(object target)
{
    Contract.Ensures(Contract.Result<ValidationResult>() != null);

    lock ( syncRoot )
    {
        if ( isValidationSuspanded )
        {
            return ValidationResult.Valid;
        }

        var rulesToExecute = GetRulesForTarget(target);

        RemoveUnregisteredValidationRuleFromMap(target ,rulesToExecute);

        if ( rulesToExecute.Any(r => !r.SupportsSyncValidation) )
        {
            throw new InvalidOperationException("There are asynchronous rules that cannot be executed synchronously. Please use ValidateAsync method to execute validation instead.");
        }

        try
        {
            ValidationResult validationResult = ExecuteValidationRules(rulesToExecute);
            return validationResult;
        }
        catch ( Exception ex )
        {
            throw new ValidationException("An exception occurred during validation. See inner exception for details." ,ex);
        }
    }
}
Now in our viewModel, we can remove the ValidationRule.
var rule = Validator.AddRule(() => LoginName ,() => RuleResult.Invalid("Login doesn't exits."));
Validator.Validate(() => LoginName);
Validator.RemoveRule(rule);
Hope this will help for someone.
I have created a fork of this project, If possible, I will request for a Pull Request
Coordinator
Jan 2, 2014 at 10:12 AM
Edited Jan 2, 2014 at 10:14 AM
Thanks for your feedback! I will fix it as soon as possible.

I have created a work item for this issue here.
Coordinator
Jan 2, 2014 at 12:00 PM
I fixed the issue. Now when you remove a rule the validation result of this rule is also removed and the ResultChanged event is fired, so that the error will disappear from the UI.

You can try it in the build here: https://mvvmvalidation.codeplex.com/downloads/get/582468.
Jan 2, 2014 at 8:43 PM
Thanks for such an quick response. I downloaded the updated copy.