Search code examples
c#wpfidataerrorinfo

Validate a field only if it is populated


I am having a problem with validating phone numbers. In our system we have two phone numbers which you can store. The problem I am having is that these are optional fields. So I want it to validate the phone number IF and only IF the user has tried to enter a phone number in there. If not it can be left as blank.

I am using the Phone attribute and have set a MaxLength. I have tried to set a MinLength to 0 but that doesn't work.

    [Phone]
    [MaxLength(24)]
    [MinLength(0)]
    public string PhoneNum1
    {
        get { return phoneNum1; }
        set
        {
            if (phoneNum1 != value)
            {
                phoneNum1 = value;
                RaisePropertyChanged("PhoneNum1");
            }
        }
    }

Additionally, we have a checkbox which if ticked the user would have to add at least one of the phone numbers. I haven't attempted this yet so I am technically not asking for that solution but it would be great if any solutions would bare this in mind.

Here is the WPF which I am using. I am using ValidatesOnDataErrors and NotifyOnValidationError

                    <TextBox Margin="0,10,0,0" Grid.Row="10"  Grid.Column="2" 
                        Text="{Binding PhoneNum1, Mode=TwoWay, ValidatesOnDataErrors=True, 
                    NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}"/>

Solution

  • You can implement your OptionalPhoneAttribute based on the original PhoneAttribute:

     public sealed class OptionalPhoneAttribute : ValidationAttribute
     {        
        public override bool IsValid(object value)
        {
            var phone = new PhoneAttribute();
    
            //return true when the value is null or empty
            //return original IsValid value only when value is not null or empty 
            return (value == null || string.IsNullOrEmpty(Convert.ToString(value)) || phone.IsValid(value));
        }
    }
    

    Then you can just use this new attribute instead:

    [OptionalPhone]
    [MaxLength(24)]
    public string PhoneNum1
    {
        get { return phoneNum1; }
        set
        {
            if (phoneNum1 != value)
            {
                phoneNum1 = value;
                RaisePropertyChanged("PhoneNum1");
            }
        }
    }