【问题标题】:WPF TextBox validation issueWPF 文本框验证问题
【发布时间】:2018-10-12 12:57:37
【问题描述】:

我有文本框,名称是 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;
                    }
                }

【问题讨论】:

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

标签: c# wpf


【解决方案1】:

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

因此,由于checkDescriptionTxtBox 有效,您应该从parameterTxtBoxTextBoxValidator 中删除ValidationStep="UpdatedValue"

但我想在源属性更新后验证值。我已经调试了 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;
}

【讨论】:

  • 感谢您的信息。但我想在源属性更新后验证值。我已经调试了 Validate 方法。在 checkDescriptionTxtBox 验证参数值作为字符串传递但当 parameterTxtBox 验证参数值不作为字符串传递而不是差异绑定值时。所以我想在源属性更新后验证值。如何做到这一点?
  • 感谢您的回复。目前我正在使用 .Net 4 。我希望是.ResolvedSource;和 .Net 4.5 中支持的 be.ResolvedSourcePropertyName。那么我如何在 .Net 4 中实现这一点?
  • string[] splits = expr.ParentBinding.Path.Path.Split('.');类型类型 = expr.DataItem.GetType(); foreach(字符串拆分为拆分){ type = type.GetProperty(split).PropertyType; }
  • 如何在我的验证方法中使用上述代码。能否请您分享验证方法的完整代码?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-21
  • 2014-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多