C# 导致绑定不更新的验证错误

C# 导致绑定不更新的验证错误,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我涉猎了WPF,发现了一个我以前从未见过的特性。在下面的示例中,我有两个文本框,它们绑定到代码隐藏中的相同DP 代码隐藏: public partial class MainWindow : Window { public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } pub

我涉猎了WPF,发现了一个我以前从未见过的特性。在下面的示例中,我有两个文本框,它们绑定到代码隐藏中的相同DP

代码隐藏:

public partial class MainWindow : Window
{
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(Window), new FrameworkPropertyMetadata("Hello"));

    public MainWindow()
    {
        InitializeComponent();
    }


}
以及XAML:

    <TextBox>
        <TextBox.Text>
            <Binding RelativeSource = "{RelativeSource Mode=FindAncestor, AncestorType=Window}" Path="Text" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
                <Binding.ValidationRules>
                    <utils:RestrictInputValidator Restriction="IntegersOnly" ValidatesOnTargetUpdated="True"/>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <TextBox Name="TextBox" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Mode=TwoWay, Path=Text, UpdateSourceTrigger=PropertyChanged}"/>

我注意到,当我在文本框中键入某个包含IntegerOnly验证但验证失败的内容时(在本例中为任何非整数的内容),底层文本变量不会更新这是默认行为吗?为什么会这样?是否可以覆盖?


将ValidationRule的ValidationStep设置为CommittedValue,该值将在值提交到源()后运行验证


编辑: validationstep设置为CommittedValue或UpdatedValue时,BindingExpression将发送到Validate方法,而不是实际值。我不知道是否有其他方法可以获取BindingExpression的值,但我创建了一个扩展方法来获取它:

public static class BindingExtensions
{
    public static T Evaluate<T>(this BindingExpression bindingExpr)
    {
        Type resolvedType = bindingExpr.ResolvedSource.GetType();
        PropertyInfo prop = resolvedType.GetProperty(
            bindingExpr.ResolvedSourcePropertyName);
        return (T)prop.GetValue(bindingExpr.ResolvedSource);
    }
}
公共静态类绑定扩展
{
公共静态T求值(此BindingExpression bindingExpr)
{
类型resolvedType=bindingExpr.ResolvedSource.GetType();
PropertyInfo prop=resolvedType.GetProperty(
bindingExpr.ResolvedSourcePropertyName);
返回(T)prop.GetValue(bindingExpr.ResolvedSource);
}
}

如果要覆盖验证,为什么要添加验证?我不会,你是对的。但是可能有一个模糊的用例,我需要查看代码隐藏中的脏数据?用户是否需要它?或者你只是需要它作为最终输入?如果您需要后者,只需添加一个按钮并弹出一个
消息框
,说明哪个字段是错误的,并且在所有验证通过之前不会继续。看一看。虽然我认为这会起作用,但这会使我的代码抛出一个
InvalidCastException
,即使我将限制更改为
Restriction=“None”
(这基本上意味着不验证)。
public static class BindingExtensions
{
    public static T Evaluate<T>(this BindingExpression bindingExpr)
    {
        Type resolvedType = bindingExpr.ResolvedSource.GetType();
        PropertyInfo prop = resolvedType.GetProperty(
            bindingExpr.ResolvedSourcePropertyName);
        return (T)prop.GetValue(bindingExpr.ResolvedSource);
    }
}