在不同级别的多个字段之间进行验证

时间:2011-12-06 09:19:10

标签: wpf validation mvvm idataerrorinfo validationrules

我遇到了多个字段之间的验证问题。例如 - 我得到了一个名为RangeDateViewModel的ViewModel,它包含名为DateViewModel的类的2个实例,每个实例分别代表一个开始日期和结束日期。

所以我的绑定看起来像这样 -

<TextBox Text="{Binding StartDate.Date, ValidateOnDataError=True}">
<TextBox Text="{Binding EndDate.Date, ValidateOnDataError=True}">

我的RangeDateViewModel类实现了IDataErrorInfo接口。 在我的计划中,RangeDateViewModel将通过在IDataErrorInfo [“propertyName”]函数中应用验证逻辑来​​验证开始日期是否在结束日期之前 -

    public string this[string columnName]
    {
         get
         {
            return ValidationError();
         }
     }

问题是永远不会调用它,而是调用驻留在每个DateViewModel类中的IDataErrorInfo属性。

我想这是因为bound属性不在RangeDateViewModel的同一级别,而是在子DateViewModel内。

我认为我的需求非常基础,必须有一个简单的解决方案来解决这个问题。 我尝试使用ValidationRules而不是IDataErrorInfo但是我遇到了问题,让ViewModel知道ValidationRules当前的验证状态。

2 个答案:

答案 0 :(得分:1)

尝试使用以下方法:

  1. DataTemplate

    创建DateViewModel
    <DataTemplate DataType="{x:Type ViewModels:DateViewModel}">
        <TextBox Text="{Binding Date}">
    </DataTemplate>
    
  2. 将此ViewModel的实例绑定到ContentControl,并在该绑定上将ValidateOnDataError设置为true

    <ContentControl Content="{Binding StartDate, ValidateOnDataError=True}" />
    <ContentControl Content="{Binding EndDate, ValidateOnDataError=True}" />
    
  3. RangeDateViewModel订阅PropertyChanged StartDate事件EndDatePropertyChanged,并在提出时,使用{{1}举办StartDate活动} / EndDate

    StartDate.PropertyChanged += (s, e) => InvokePropertyChanged("StartDate");
    EndDate.PropertyChanged += (s, e) => InvokePropertyChanged("EndDate");
    

答案 1 :(得分:1)

我遇到的问题是public string this[string columnName]在其他一周内根本没有被调用。

解决方案很简单。 绑定的WPF绑定引擎无法跟踪我的ViewModel的嵌套。

我曾假设我需要在ViewModel中实现当前DataContext的属性,但是而不是它需要在绑定到控件的ViewModel中实现

示例:

<TextBox Text="{Binding Path=ProductViewModel.DescriptionViewModel.ProductName,
                                    Mode=TwoWay,
                                    ValidatesOnDataErrors=True,
                                    NotifyOnValidationError=True}" />

此处DescriptionViewModel是包含绑定属性的类。 IDataErrorInfo需要在该类中实现({strong>不ProductViewModel或其他类可能包含它),然后一切都会正常工作。