3

我的窗口上有以下 Loaded 事件:

void Window_Loaded(object sender, RoutedEventArgs e) {
    this.DataContext = new MyObject() {
        MyDateTime = DateTime.Now,
        MyNotEmptyString = "Not Empty",
        MyNotUpperCaseString = "not upper case",
        MyInteger = 20,
        MyIntegerInRange = 1,
        MyDouble = 4.56
    };
}

对于上面初始化的每个属性,我都有一个TextBox绑定到它的属性,每个属性都有与之关联的自己的验证规则。

问题是,我的验证规则在设置时不是第一次运行this.DataContext,但在表单正常使用时效果很好(它们在TextBox失去焦点时运行)。这背后的原因可能是什么?我试过设置UpdateSourceTrigger="PropertyChanged",但这没有帮助。

编辑: 这是一个TextBox绑定到属性的示例:

<TextBox Name="MyDoubleField">
    <TextBox.Text>
        <Binding Path="MyDouble">
            <Binding.ValidationRules>
                <local:TextIsDouble/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>
4

3 回答 3

3

“为什么”部分的答案很简单:这是设计使然。验证通常适用于用户输入,而不是用于验证存储的数据。

我认为根本问题是:如何在设置上下文后手动激活验证。我不确定,但也许 WPF 窗口有类似 WinForms Validate() 方法的东西。

于 2009-07-16T13:45:06.153 回答
0

您的验证不在您的数据类中是否有原因?使用 IDataErrorInfo 应该立即验证数据,然后将其冒泡到您的 UI,而无需执行任何额外操作。

我说应该,因为这对我们有用,但我们不使用 WPF。

于 2009-07-16T14:36:01.203 回答
0

设置 DataContext 时未运行验证的原因是,WPF 仅在使用来自目标的值更新源时运行验证(也就是更改文本框并相应更新源)。

如果要在设置 DataContext 时验证数据,则必须迭代逻辑树,并且对于要运行验证的每个元素,都需要获取其 BindingExpression,然后调用绑定 Expression UpdateSource 方法. 这将强制进行验证。

执行类似操作的代码是:

    private void ValidateData()
    {            
        //The XAML file defines a group of TextBox elements inside a Grid called grd
        foreach (UIElement uie in grd.Children)
        {
            if (uie.GetType() == typeof(TextBox))
            {
                ((TextBox)uie).GetBindingExpression(TextBox.TextProperty).UpdateSource();          
            }
        }                    
    }
于 2009-07-17T05:12:50.300 回答