0

Here's the XAML code representing a TextBox used as input for the IdCard

  <TextBox.Text>
     <Binding Mode="TwoWay"
              Path="IdCardNumber"
              UpdateSourceTrigger="PropertyChanged">
                 <Binding.ValidationRules>
                    <v:AlphaNumValidationRule ValidationStep="UpdatedValue" />
                 </Binding.ValidationRules>
     </Binding>
  </TextBox.Text>

The validation :

public class AlphaNumValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        if (string.IsNullOrWhiteSpace((value ?? "").ToString()))
            return new ValidationResult(false, Resources.Strings.MessagesResource.RequiredField);
        else if (value.ToString().MatchRegex(RegexResource.ALPHANUMERIC))
            return new ValidationResult(true, null);
        else
            return new ValidationResult(false, Resources.Strings.MessagesResource.InvalidFormat);
    }
}

The ViewModel

    public override bool IsValid
    {
        get { return !string.IsNullOrWhiteSpace(IdCardNumber); }
    }
    private string idCardNumber;
    public string IdCardNumber
    {
        get { return idCardNumber; }
        set { Set(() => IdCardNumber, ref idCardNumber, value);
            RaisePropertyChanged("IsValid");
        }
    }

What I want to have is to update IsValid everytime the IdCard input is updated , I tried different ValidationStep but none do as I wish.

At first when loading the input for the first time IsValid is false , when typing a correct value it becomes true after deleting input and adding wrong non-supported values IsValid stays the same since it keeps the last correct value.

Any way to solve this ?

Taoufik J
  • 700
  • 1
  • 9
  • 26
  • Here is my post how to use validation: http://stackoverflow.com/questions/19539492/wpf-textbox-validation-c-sharp/37255232#37255232 – Mr.B Aug 24 '16 at 14:42
  • @Mr.B I want a specific behavior as explained in my post for this validation – Taoufik J Aug 24 '16 at 15:01

2 Answers2

3

There is an attached event Validation.Error that is fired when binding error occurs.

So basically you could attach to this event and set value of Validation.HasErrors property to your viewmodel's IsValid property.

I see a conflict however. You defined your validation logic in the View, but you want to access it in your ViewModel, that's why you are having troubles.

I recommend you to move entire validation logic to your viewmodel by implementing INotifyDataErrorInfo. then you will have all validation rules and validation errors at your disposal in viewmodel.

Liero
  • 25,216
  • 29
  • 151
  • 297
1

You can try to change the UpdateSourceTrigger property with LostFocus:

 <Binding Mode="TwoWay"
          Path="IdCardNumber"
          UpdateSourceTrigger="LostFocus">
             <Binding.ValidationRules>
                <v:AlphaNumValidationRule ValidationStep="UpdatedValue" />
             </Binding.ValidationRules>
 </Binding>

Edit :

To bind the validation result you can use HasError property :

   <TextBox Name="TextBox">
            <TextBox.Text>
                <Binding Mode="TwoWay"
              Path="Text"
              UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <local:AlphaNumValidationRule/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
   <TextBlock Text="{Binding (Validation.HasError), ElementName=TextBox}"/>
Quentin Roger
  • 6,410
  • 2
  • 23
  • 36
  • I don't want to use LostFocus I'd like it to update IsValid in real time. the ValidationStep you're using stores the wrong value(due to IsValid getter, and verifying only if the input is empty or not) and also keeps warning message of the wrong input triggered . – Taoufik J Aug 24 '16 at 14:57
  • Sorry I misunderstood your question. Why you need this "IsValid" boolean ? If you want to bind the result of the validation you can use : `{Binding (Validation.HasError), ElementName=TextBox}` – Quentin Roger Aug 25 '16 at 07:29
  • 1
    And how to use Validation.HasError from the other side (ViewModel) ? – Taoufik J Aug 25 '16 at 13:49