Arunagiri
Arunagiri

Reputation: 29

WPF TextBox validation issue

I have textbox those name are checkDescriptionTxtBox and parameterTxtBox. Both are using same validation rule such are available in TextBoxValidator.cs. But the one difference is ValidationStep="UpdatedValue" added in parameterTxtBox. checkDescriptionTxtBox validation working as expected but Why parameterTxtBox validation not working?Could you please help anyone.

i want to validate the value after source property has been updated. I have debugged the Validate method. During checkDescriptionTxtBox validation parameter value passing as string but when parameterTxtBox validation parameter value not passing as string instead difference binding value. So i want to validate the value after the source property has been updated. How to achieve this?

<TextBox Name="checkDescriptionTxtBox" Width="700" TextWrapping="Wrap" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Auto" Validation.ErrorTemplate="{StaticResource validationErrorTemplate}">
                                <TextBox.Text>
                                    <Binding Path="CheckDescription" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
                                        <Binding.ValidationRules>
                                            <v:TextBoxValidator></v:TextBoxValidator>
                                        </Binding.ValidationRules>
                                    </Binding>
                                </TextBox.Text>
                            </TextBox>

<TextBox Name="parameterTxtBox" Margin="10,0,0,0" Width="200" Height="20" Validation.ErrorTemplate="{StaticResource validationErrorTemplate}">
                                                <TextBox.Text>
                                                    <Binding Path="ParameterValue" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" >
                                                        <Binding.ValidationRules>
                                                            <v:TextBoxValidator ValidationStep="UpdatedValue"></v:TextBoxValidator>
                                                        </Binding.ValidationRules>
                                                    </Binding>
                                                </TextBox.Text>
                                            </TextBox>


    TextBoxValidator.cs    
        public class TextBoxValidator : ValidationRule
            {
             public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
                    {
                        if (String.IsNullOrEmpty(value.ToString().Trim()))
                            return new ValidationResult(false, "Value cannot be empty");

                        return ValidationResult.ValidResult;
                    }
                }

Upvotes: 1

Views: 489

Answers (1)

mm8
mm8

Reputation: 169390

Setting the ValidationStep property to UpdatedValue means that the validation rule will be run after the source property has been updated. If the source property isn't updated, the validation rule won't run. The default value of the ValidationStep property is RawProposedValue which means that the validation rule is run before the value conversion occurs.

So since the checkDescriptionTxtBox works, you should simply remove ValidationStep="UpdatedValue" form the TextBoxValidator of parameterTxtBox.

But i want to validate the value after source property has been updated. I have debugged the Validate method. During checkDescriptionTxtBox validation parameter value passing as string but when parameterTxtBox validation parameter value not passing as string instead difference binding value. So i want to validate the value after the source property has been updated. How to achieve this?

Cast the value to BindingExpression a use some reflection:

public class TextBoxValidator : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        string s = null;
        BindingExpression be = value as BindingExpression;
        if(be != null)
        {
            object sourceObject = be.ResolvedSource;
            string sourceProperty = be.ResolvedSourcePropertyName;
            if(sourceObject != null && sourceProperty != null)
            {
                PropertyInfo pi = sourceObject.GetType().GetProperty(sourceProperty);
                s = pi.GetValue(sourceObject) as string;

            }
        }
        else
        {
            s = value as string;
        }

        if (string.IsNullOrEmpty(s))
            return new ValidationResult(false, "Value cannot be empty");

        return ValidationResult.ValidResult;
    }
}

Currently i am using .Net 4 . I hope be.ResolvedSource; and be.ResolvedSourcePropertyName supported in .Net 4.5. Then how can i achieve this in .Net 4?

This should work in .NET Framework 4:

public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
    string s = null;
    BindingExpression be = value as BindingExpression;
    if (be != null)
    {
        object sourceObject = be.DataItem;
        string sourceProperty = be.ParentBinding.Path.Path;
        if (sourceObject != null && sourceProperty != null)
        {
            PropertyInfo pi = sourceObject.GetType().GetProperty(sourceProperty);
            s = pi.GetValue(sourceObject) as string;

        }
    }
    else
    {
        s = value as string;
    }

    if (string.IsNullOrEmpty(s))
        return new ValidationResult(false, "Value cannot be empty");

    return ValidationResult.ValidResult;
}

Upvotes: 1

Related Questions