【问题标题】:Validation Errors causing binding to not update导致绑定不更新的验证错误
【发布时间】:2013-07-11 20:12:09
【问题描述】:

我在涉足 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}"/>

我注意到,当我在 TextBox 中键入包含 IntegerOnly 验证但验证失败的内容时(在这种情况下,任何不是整数的内容),底层 Text 变量都不会更新。 这是默认行为吗?为什么这样做?是否可以覆盖?

【问题讨论】:

  • 如果要覆盖它,为什么要添加验证?
  • 我不会,你是对的。但是可能有一个晦涩的用例,我需要查看代码隐藏中的脏数据。
  • 您需要在哪里进行验证?用户需要它吗?还是您只需要它作为最终输入?如果您需要它用于后者,只需添加一个按钮并弹出一个MessageBox,说明哪个字段是错误的,并且在所有验证通过之前不要继续。看看this

标签: c# .net wpf xaml


【解决方案1】:

将 ValidationRule 的 ValidationStep 设置为 CommitedValue,这将在将值提交到源 (msdn) 后运行验证。

<utils:RestrictInputValidator Restriction="IntegersOnly" ValidationStep="CommitedValue" ValidatesOnTargetUpdated="True"/>

编辑: 将validationstep 设置为CommitedValue 或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);
    }
}

【讨论】:

  • 虽然我认为这会起作用,但这会让我的代码抛出一个InvalidCastException,即使我将我的限制更改为Restriction="None"(这实际上意味着不验证)。
猜你喜欢
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-03
  • 2022-01-23
  • 2013-02-04
  • 1970-01-01
  • 2013-06-12
相关资源
最近更新 更多