首页 > 解决方案 > WPF 文本框验证问题

问题描述

我有文本框,这些名称是 checkDescriptionTxtBox 和 parameterTxtBox。两者都使用相同的验证规则,例如在 TextBoxValidator.cs 中可用。但一个区别是在 parameterTxtBox 中添加了 ValidationStep="UpdatedValue"。checkDescriptionTxtBox 验证按预期工作,但为什么 parameterTxtBox 验证不起作用?你能帮助任何人吗?

我想在源属性更新后验证值。我已经调试了 Validate 方法。在 checkDescriptionTxtBox 验证参数值作为字符串传递但当 parameterTxtBox 验证参数值不作为字符串传递而是差异绑定值时。所以我想在源属性更新后验证值。如何做到这一点?

<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;
                    }
                }

标签: c#wpf

解决方案


ValidationStep属性设置为UpdatedValue意味着验证规则将在源属性更新后运行。如果源属性未更新,验证规则将不会运行。该ValidationStep属性的默认值是RawProposedValue表示验证规则在值转换发生之前运行。

因此,由于checkDescriptionTxtBox有效,您应该简单地从ValidationStep="UpdatedValue"ofTextBoxValidator中删除parameterTxtBox

但我想在源属性更新后验证值。我已经调试了 Validate 方法。在 checkDescriptionTxtBox 验证参数值作为字符串传递但当 parameterTxtBox 验证参数值不作为字符串传递而不是差异绑定值时。所以我想在源属性更新后验证值。如何做到这一点?

使用value一些BindingExpression反射:

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;
    }
}

目前我正在使用 .Net 4 。我希望是.ResolvedSource; 和 .Net 4.5 中支持的 be.ResolvedSourcePropertyName。那么我如何在.Net 4中实现这一点?

这应该适用于 .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;
}

推荐阅读