如何从IDataErrorInfo显示不同列上的验证错误
本文关键字:验证 错误 IDataErrorInfo 显示 | 更新日期: 2023-09-27 18:14:18
问题:我希望在UI上包含输入文本框的默认错误,但在一个字段中的输入需要突出显示其他多个有错误的文本框。
示例:如果所有文本框都为空,则没有错误。如果只有一个文本框有字符串,那么其他两个文本框都应该高亮显示。(包含数据的文本框不是错误,但其他两个——如果为空——现在是错误的)。如果该字符串随后被删除并且所有文本框都为空,则不会出现错误,也不会突出显示任何内容。
我似乎找不到这个简单问题的答案。我有一个具有三个属性的业务对象(MVVM),每个属性都绑定到XAML中的一个文本框,如下: <wc:AutoFilteredComboBox
..
Text="{Binding ReferredBy.NewReferralName, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
....
/>
<TextBox
Text="{Binding ReferredBy.Phone, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
/>
<TextBox
......
Text="{Binding ReferredBy.PriorAuthorizationNumber, ValidatesOnDataErrors=True}"
/>
和ViewModel实现IDataErrorInfo:
public string Error
{
get { return null; }
}
// any returned non-empty string is an error.
public string this[string columnName]
{
get
{
switch (columnName)
{
case "NewReferralName":
if (!String.IsNullOrWhiteSpace(PriorAuthorizationNumber) || !String.IsNullOrWhiteSpace(Phone))
{
if (String.IsNullOrWhiteSpace(NewReferralName))
return "NewReferralName is invalid";
}
break;
case "Phone":
if (!String.IsNullOrWhiteSpace(NewReferralName) && String.IsNullOrWhiteSpace(Phone))
{
return "Phone is invalid";
}
break;
case "PriorAuthorizationNumber":
if (!String.IsNullOrWhiteSpace(NewReferralName) && String.IsNullOrWhiteSpace(PriorAuthorizationNumber))
{
return "PriorAuthorizationNumber is invalid";
}
break;
}
// string.Empty is no error.
return string.Empty;
}
}
所以,如果数据输入到一个文本框,如何显示错误的另一个文本框的?IDataErrorInfo是否可以用于此,或者有更好的方法?
TIA
当然,您可以使用IDataErrorInfo来实现这一点。这里的技巧是"告诉"视图在INotifyPropertyChanged的帮助下重新评估验证。当用户改变一个属性的值时,ViewModel不仅要通知View这个属性被改变了,还要通知其他相关的属性。
例如:public class ViewModel : INotifyPropertyChanged, IDataErrorInfo
{
// Do this for each involved property in your ViewModel
private string _newReferralName;
public string NewReferralName
{
get { return _newReferralName; }
set
{
_name = value;
RaisePropertyChanged("NewReferralName");
// The tricky part. Notify that the related properties
// have to be refreshed (in the View) and, thus, reevaluated
RaisePropertyChanged("Phone");
RaisePorpertyChanged("PriorAuthorizationNumber");
}
}
...
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}