S / L 4& IDataErrorInfo - 如何强制重新验证控件(触及相关控件时)

时间:2011-01-13 23:54:30

标签: silverlight validation idataerrorinfo

我有两个绑定到属性MinCartValue和MaxCartValue的控件。 MinCartValue必须小于MaxCartValue。为了实现这个验证,我实现了IDataErrorInfo接口,如果触摸了MinCartValue或MaxCartValue,则在this [columnName]方法中运行上面的检查。在两个控件的绑定中设置ValidatesOnDataErrors = True。 验证工作正常,当其属性值的更改违反规则时突出显示每个控件。问题是一旦控件被标记为无效,如果用户通过改变其他控件的值来纠正问题,则第一个控件仍然被标记为无效。这是可以理解的,因为IDataErrorInfo方法没有对第一个控件的属性进行验证。

所以我需要的是一种在属性#2被验证时强制属性#1被重新验证(或清除无效状态的方法)的方法,反之亦然。我试过在我的[columnName]方法中调用RaisePropertyChanged,但它什么也没做。还尝试将属性设置为自己的值以尝试欺骗它以验证自身,但是没有任何反应。

由于

4 个答案:

答案 0 :(得分:2)

我建议查看INotifyDataErrorInfo接口(在Silverlight 4中引入)。如果属性变得无效,它可以异步通知,所以我认为框架更好地在许多属性中尊重它,而不是期望当前正在更改的属性是唯一有效性可能正在改变的属性。

答案 1 :(得分:1)

我有两个需要相互验证的DateTime属性(DateFrom和DateTo)。在这些属性的setter中,我刚刚为DateTo和DateFrom引发了一个PropertyChanged事件。工作就像一个魅力。

答案 2 :(得分:0)

我不确定我是否完全理解你的问题,但也许这可能有所帮助。提供一些示例XAML和绑定属性代码会有所帮助。

这听起来像是代码的问题,具体取决于默认的UpdateSourceTrigger,在TextBox控件的情况下,它是焦点/非焦点。您可以通过将UpdateSourceTrigger = Explicit添加到您的验证发生的绑定,在XAML中设置UpdateSourceTrigger属性。然后在每个TextBox(MinCartValue,MaxCartValue)中,为TextChanged事件添加一个事件处理程序。

在事件处理程序的代码隐藏中,您可以执行以下操作:

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        TheTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
    }

在这种情况下,TheTextBox将是您的购物车控件之一。 UpdateSource()方法是一种手动更新绑定值的方法,它应该触发您的验证。此方法提供绑定到触发器以更新值,并且提升属性已在默认范围之外更改(在此实例中使用文本更改的焦点和未聚焦的TextBox)。

答案 3 :(得分:0)

以下是我如何解决它。假设Property1和Property2是相互依赖的。我还不熟悉MVVM,但你可能正在扩展你的实体类来实现IDataErrorInfo。在这种情况下,您还可以扩展On [Property] Changed方法并报告相关属性中的更改:

partial class YourEntity : IDataErrorInfo
{
    public string this[string columnName]
        {
            //Your validation logic
        }

    public string Error
    {
        //WPF doesn't use it anyway
        get { return string.Empty; }
    }

    partial void OnProperty1Changed() 
    {
        OnPropertyChanging("Property2");
        OnPropertyChanged("Property2");
    }

    partial void OnProperty2Changed()
    {
        OnPropertyChanging("Property1");
        OnPropertyChanged("Property1");
    }
}

在这种情况下,任何一个属性中的更新都会使绑定控件重新进行自我评估。

EDIT2:您似乎应该使用OnPropertyChang *而不是ReportPropertyChang *。 ReportPropertyChanged将通知实体框架模型中存在挂起的更改,但实际上您要做的就是通知视图。您不希望使用未真正更改的属性更新数据库。对于在数据库中没有映射的计算字段,ReportPropertyChang *也将失败。 EDIT1:发现在ReportPropertyChanged之前调用ReportPropertyChanging是必不可少的。