Search code examples
wpfvalidationdata-bindingmvvm-lightvalidationrules

WPF MVVMLight Setter not fired on binding TextBox when validation rule is invalid


I have a TextBox with binding on Mo property :

<TextBox>
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Style.Setters>
                <Setter Property="Text">
                    <Setter.Value>
                        <Binding Path="Mo" UpdateSourceTrigger="PropertyChanged">
                            <Binding.ValidationRules>
                                <validator:FloatPositiveValidationRule ValidatesOnTargetUpdated="True" />
                            </Binding.ValidationRules>
                        </Binding>
                    </Setter.Value>
                </Setter>
            </Style.Setters>
        </Style>
    </TextBox.Style>
</TextBox>

This one contains a validation rule which validate the control only if the value is not empty and greater than 0 :

public class FloatPositiveValidationRule : ValidationRule
{        
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string str = (string)value;

        if (str.Length > 0)
        {
            double mo = Double.Parse(str.Replace(".", ","));

            if (mo > 0)
                return new ValidationResult(true, null);
            else
                return new ValidationResult(false, "Must be greater than 0");
        }
        else
            return new ValidationResult(false, "Empty");
    }
}

In my view model, when the validation is false, the setter is not fired :

private double? _mo;
public string Mo
{
    get { return _mo.ToString(); }

    set
    {
        if (value != "")
            mo = double.Parse(value.Replace(".", ","));

        Set(ref _mo, mo);
    }
}

Is it possible to enter in the setter even if the validation is invalid ?


Solution

  • You could try to set ValidationStep property to UpdatedValue:

    <validator:FloatPositiveValidationRule ValidatesOnTargetUpdated="True" ValidationStep="UpdatedValue"  />
    

    This should make the validation rule run after the source property has been set.

    But what you really should do is to remove the ValidationRule and implement the validation logic in your view model, for example by implementing the INotifyDataErrorInfo interface.