AymenDaoudi
AymenDaoudi

Reputation: 8309

Enforce validation on a TexBox when text changes in WPF

I'm using Validation on TextBox as follows

<TextBox BorderThickness="1" Style="{DynamicResource TextBoxInError}"
Validation.ErrorTemplate="{StaticResource ValidationTemplate}">
     <TextBox.Text>
         <Binding Path="TimeBeforeDeletingPicture" Mode="TwoWay">
              <Binding.ValidationRules>
                   <helpers:TimeBeforeDeletingRule/>
              </Binding.ValidationRules>
         </Binding>
     </TextBox.Text>
</TextBox>

The validation fires when I leave the TextBox (apparently when it looses focus), I want to validate the input every time the text changes, I'm using MVVM so I don't want to mess with events, what's the correct clean way to achieve that.

Upvotes: 2

Views: 1713

Answers (2)

Vlad S.
Vlad S.

Reputation: 458

I know it is old post but maybe it can still help someone.

By default, UpdateSourceTrigger=LostFocus for a TextBox control. That is why the validation triggers only then, at LostFocus. Sure you can change to UpdateSourceTrigger= PropertyChanged. But you might want to validate and apply the error template as you type, but update the source model property only when losing focus. I needed this anyway.

This is how you can validate the textbox without updating the source, that is validate on the TextChanged handler:

    internal void mytextbox_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox txtBox = sender as TextBox;
        BindingExpression bindingExpression = BindingOperations.GetBindingExpression(txtBox, TextBox.TextProperty);

        if (!IsMyTextBoxValid(((TextBox)sender).Text))
        {
            BindingExpressionBase bindingExpressionBase = BindingOperations.GetBindingExpressionBase(txtBox, TextBox.TextProperty);
            ValidationError validationError = new ValidationError(new ExceptionValidationRule(), bindingExpression);
            validationError.ErrorContent = "This value is not valid for my textbox";
            Validation.MarkInvalid(bindingExpressionBase, validationError);
        }
        else
            Validation.ClearInvalid(bindingExpression);
    }

Upvotes: 0

Maximus
Maximus

Reputation: 3448

Set UpdateSourcetrigger as follows

 <TextBox.Text>
            <Binding Path="TimeBeforeDeletingPicture" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>

Upvotes: 2

Related Questions